1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 7*7c478bd9Sstevel@tonic-gate 8*7c478bd9Sstevel@tonic-gate /* 9*7c478bd9Sstevel@tonic-gate * kdc/main.c 10*7c478bd9Sstevel@tonic-gate * 11*7c478bd9Sstevel@tonic-gate * Copyright 1990,2001 by the Massachusetts Institute of Technology. 12*7c478bd9Sstevel@tonic-gate * 13*7c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may 14*7c478bd9Sstevel@tonic-gate * require a specific license from the United States Government. 15*7c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 16*7c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting. 17*7c478bd9Sstevel@tonic-gate * 18*7c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 19*7c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 20*7c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 21*7c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 22*7c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 23*7c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 24*7c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 25*7c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 26*7c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a 27*7c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 28*7c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 29*7c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 30*7c478bd9Sstevel@tonic-gate * or implied warranty. 31*7c478bd9Sstevel@tonic-gate * 32*7c478bd9Sstevel@tonic-gate * 33*7c478bd9Sstevel@tonic-gate * Main procedure body for the KDC server process. 34*7c478bd9Sstevel@tonic-gate */ 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate #include <stdio.h> 37*7c478bd9Sstevel@tonic-gate #include <syslog.h> 38*7c478bd9Sstevel@tonic-gate #include <signal.h> 39*7c478bd9Sstevel@tonic-gate #include <errno.h> 40*7c478bd9Sstevel@tonic-gate #include <netdb.h> 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate #include "k5-int.h" 43*7c478bd9Sstevel@tonic-gate #include "com_err.h" 44*7c478bd9Sstevel@tonic-gate #include "adm.h" 45*7c478bd9Sstevel@tonic-gate #include "adm_proto.h" 46*7c478bd9Sstevel@tonic-gate #include "kdc_util.h" 47*7c478bd9Sstevel@tonic-gate #include "extern.h" 48*7c478bd9Sstevel@tonic-gate #include "kdc5_err.h" 49*7c478bd9Sstevel@tonic-gate #include <libintl.h> 50*7c478bd9Sstevel@tonic-gate #include <locale.h> 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate #ifdef HAVE_NETINET_IN_H 53*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 54*7c478bd9Sstevel@tonic-gate #endif 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate kdc_realm_t *find_realm_data PROTOTYPE((char *, krb5_ui_4)); 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate void usage PROTOTYPE((char *)); 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate krb5_sigtype request_exit PROTOTYPE((int)); 61*7c478bd9Sstevel@tonic-gate krb5_sigtype request_hup PROTOTYPE((int)); 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate void setup_signal_handlers PROTOTYPE((void)); 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate krb5_error_code setup_sam PROTOTYPE((void)); 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate void initialize_realms PROTOTYPE((krb5_context, int, char **)); 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate void finish_realms PROTOTYPE((char *)); 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate static int nofork = 0; 72*7c478bd9Sstevel@tonic-gate static int rkey_init_done = 0; 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate /* Solaris Kerberos: global here that other functions access */ 75*7c478bd9Sstevel@tonic-gate int max_tcp_data_connections; 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGNALS 78*7c478bd9Sstevel@tonic-gate static struct sigaction s_action; 79*7c478bd9Sstevel@tonic-gate #endif /* POSIX_SIGNALS */ 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate #define KRB5_KDC_MAX_REALMS 32 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate /* 84*7c478bd9Sstevel@tonic-gate * Find the realm entry for a given realm. 85*7c478bd9Sstevel@tonic-gate */ 86*7c478bd9Sstevel@tonic-gate kdc_realm_t * 87*7c478bd9Sstevel@tonic-gate find_realm_data(rname, rsize) 88*7c478bd9Sstevel@tonic-gate char *rname; 89*7c478bd9Sstevel@tonic-gate krb5_ui_4 rsize; 90*7c478bd9Sstevel@tonic-gate { 91*7c478bd9Sstevel@tonic-gate int i; 92*7c478bd9Sstevel@tonic-gate for (i=0; i<kdc_numrealms; i++) { 93*7c478bd9Sstevel@tonic-gate if ((rsize == strlen(kdc_realmlist[i]->realm_name)) && 94*7c478bd9Sstevel@tonic-gate !strncmp(rname, kdc_realmlist[i]->realm_name, rsize)) 95*7c478bd9Sstevel@tonic-gate return(kdc_realmlist[i]); 96*7c478bd9Sstevel@tonic-gate } 97*7c478bd9Sstevel@tonic-gate return((kdc_realm_t *) NULL); 98*7c478bd9Sstevel@tonic-gate } 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate krb5_error_code 101*7c478bd9Sstevel@tonic-gate setup_server_realm(sprinc) 102*7c478bd9Sstevel@tonic-gate krb5_principal sprinc; 103*7c478bd9Sstevel@tonic-gate { 104*7c478bd9Sstevel@tonic-gate krb5_error_code kret; 105*7c478bd9Sstevel@tonic-gate kdc_realm_t *newrealm; 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate kret = 0; 108*7c478bd9Sstevel@tonic-gate if (kdc_numrealms > 1) { 109*7c478bd9Sstevel@tonic-gate if (!(newrealm = find_realm_data(sprinc->realm.data, 110*7c478bd9Sstevel@tonic-gate (krb5_ui_4) sprinc->realm.length))) 111*7c478bd9Sstevel@tonic-gate kret = ENOENT; 112*7c478bd9Sstevel@tonic-gate else 113*7c478bd9Sstevel@tonic-gate kdc_active_realm = newrealm; 114*7c478bd9Sstevel@tonic-gate } 115*7c478bd9Sstevel@tonic-gate else 116*7c478bd9Sstevel@tonic-gate kdc_active_realm = kdc_realmlist[0]; 117*7c478bd9Sstevel@tonic-gate return(kret); 118*7c478bd9Sstevel@tonic-gate } 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate static void 121*7c478bd9Sstevel@tonic-gate finish_realm(rdp) 122*7c478bd9Sstevel@tonic-gate kdc_realm_t *rdp; 123*7c478bd9Sstevel@tonic-gate { 124*7c478bd9Sstevel@tonic-gate if (rdp->realm_dbname) 125*7c478bd9Sstevel@tonic-gate free(rdp->realm_dbname); 126*7c478bd9Sstevel@tonic-gate if (rdp->realm_mpname) 127*7c478bd9Sstevel@tonic-gate free(rdp->realm_mpname); 128*7c478bd9Sstevel@tonic-gate if (rdp->realm_stash) 129*7c478bd9Sstevel@tonic-gate free(rdp->realm_stash); 130*7c478bd9Sstevel@tonic-gate if (rdp->realm_ports) 131*7c478bd9Sstevel@tonic-gate free(rdp->realm_ports); 132*7c478bd9Sstevel@tonic-gate if (rdp->realm_tcp_ports) 133*7c478bd9Sstevel@tonic-gate free(rdp->realm_tcp_ports); 134*7c478bd9Sstevel@tonic-gate if (rdp->realm_kstypes) 135*7c478bd9Sstevel@tonic-gate free(rdp->realm_kstypes); 136*7c478bd9Sstevel@tonic-gate if (rdp->realm_keytab) 137*7c478bd9Sstevel@tonic-gate krb5_kt_close(rdp->realm_context, rdp->realm_keytab); 138*7c478bd9Sstevel@tonic-gate if (rdp->realm_context) { 139*7c478bd9Sstevel@tonic-gate if (rdp->realm_mprinc) 140*7c478bd9Sstevel@tonic-gate krb5_free_principal(rdp->realm_context, rdp->realm_mprinc); 141*7c478bd9Sstevel@tonic-gate if (rdp->realm_mkey.length && rdp->realm_mkey.contents) { 142*7c478bd9Sstevel@tonic-gate memset(rdp->realm_mkey.contents, 0, rdp->realm_mkey.length); 143*7c478bd9Sstevel@tonic-gate free(rdp->realm_mkey.contents); 144*7c478bd9Sstevel@tonic-gate } 145*7c478bd9Sstevel@tonic-gate if (rdp->realm_tgskey.length && rdp->realm_tgskey.contents) { 146*7c478bd9Sstevel@tonic-gate memset(rdp->realm_tgskey.contents, 0, rdp->realm_tgskey.length); 147*7c478bd9Sstevel@tonic-gate free(rdp->realm_tgskey.contents); 148*7c478bd9Sstevel@tonic-gate } 149*7c478bd9Sstevel@tonic-gate krb5_db_fini(rdp->realm_context); 150*7c478bd9Sstevel@tonic-gate if (rdp->realm_tgsprinc) 151*7c478bd9Sstevel@tonic-gate krb5_free_principal(rdp->realm_context, rdp->realm_tgsprinc); 152*7c478bd9Sstevel@tonic-gate krb5_free_context(rdp->realm_context); 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate free(rdp); 155*7c478bd9Sstevel@tonic-gate } 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate /* 158*7c478bd9Sstevel@tonic-gate * Initialize a realm control structure from the alternate profile or from 159*7c478bd9Sstevel@tonic-gate * the specified defaults. 160*7c478bd9Sstevel@tonic-gate * 161*7c478bd9Sstevel@tonic-gate * After we're complete here, the essence of the realm is embodied in the 162*7c478bd9Sstevel@tonic-gate * realm data and we should be all set to begin operation for that realm. 163*7c478bd9Sstevel@tonic-gate */ 164*7c478bd9Sstevel@tonic-gate static krb5_error_code 165*7c478bd9Sstevel@tonic-gate init_realm(progname, rdp, realm, def_dbname, def_mpname, 166*7c478bd9Sstevel@tonic-gate def_enctype, def_udp_ports, def_tcp_ports, def_manual) 167*7c478bd9Sstevel@tonic-gate char *progname; 168*7c478bd9Sstevel@tonic-gate kdc_realm_t *rdp; 169*7c478bd9Sstevel@tonic-gate char *realm; 170*7c478bd9Sstevel@tonic-gate char *def_dbname; 171*7c478bd9Sstevel@tonic-gate char *def_mpname; 172*7c478bd9Sstevel@tonic-gate krb5_enctype def_enctype; 173*7c478bd9Sstevel@tonic-gate char *def_udp_ports; 174*7c478bd9Sstevel@tonic-gate char *def_tcp_ports; 175*7c478bd9Sstevel@tonic-gate krb5_boolean def_manual; 176*7c478bd9Sstevel@tonic-gate { 177*7c478bd9Sstevel@tonic-gate krb5_error_code kret; 178*7c478bd9Sstevel@tonic-gate krb5_boolean manual; 179*7c478bd9Sstevel@tonic-gate krb5_db_entry db_entry; 180*7c478bd9Sstevel@tonic-gate int num2get; 181*7c478bd9Sstevel@tonic-gate krb5_boolean more; 182*7c478bd9Sstevel@tonic-gate krb5_boolean db_inited; 183*7c478bd9Sstevel@tonic-gate krb5_realm_params *rparams; 184*7c478bd9Sstevel@tonic-gate krb5_key_data *kdata; 185*7c478bd9Sstevel@tonic-gate krb5_key_salt_tuple *kslist; 186*7c478bd9Sstevel@tonic-gate krb5_int32 nkslist; 187*7c478bd9Sstevel@tonic-gate int i; 188*7c478bd9Sstevel@tonic-gate krb5_deltat now, krb5_kdb_max_time; 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate db_inited = 0; 191*7c478bd9Sstevel@tonic-gate memset((char *) rdp, 0, sizeof(kdc_realm_t)); 192*7c478bd9Sstevel@tonic-gate if (!realm) { 193*7c478bd9Sstevel@tonic-gate kret = EINVAL; 194*7c478bd9Sstevel@tonic-gate goto whoops; 195*7c478bd9Sstevel@tonic-gate } 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate rdp->realm_name = realm; 198*7c478bd9Sstevel@tonic-gate kret = krb5_init_context(&rdp->realm_context); 199*7c478bd9Sstevel@tonic-gate if (kret) { 200*7c478bd9Sstevel@tonic-gate com_err(progname, kret, gettext("while getting context for realm %s"), 201*7c478bd9Sstevel@tonic-gate realm); 202*7c478bd9Sstevel@tonic-gate goto whoops; 203*7c478bd9Sstevel@tonic-gate } 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate kret = krb5_read_realm_params(rdp->realm_context, rdp->realm_name, 206*7c478bd9Sstevel@tonic-gate (char *) NULL, (char *) NULL, &rparams); 207*7c478bd9Sstevel@tonic-gate if (kret) { 208*7c478bd9Sstevel@tonic-gate com_err(progname, kret, gettext("while reading realm parameters")); 209*7c478bd9Sstevel@tonic-gate goto whoops; 210*7c478bd9Sstevel@tonic-gate } 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate /* Handle profile file name */ 213*7c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_profile) 214*7c478bd9Sstevel@tonic-gate rdp->realm_profile = strdup(rparams->realm_profile); 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate /* Handle database name */ 217*7c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_dbname) 218*7c478bd9Sstevel@tonic-gate rdp->realm_dbname = strdup(rparams->realm_dbname); 219*7c478bd9Sstevel@tonic-gate else 220*7c478bd9Sstevel@tonic-gate rdp->realm_dbname = (def_dbname) ? strdup(def_dbname) : 221*7c478bd9Sstevel@tonic-gate strdup(DEFAULT_KDB_FILE); 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate /* Handle master key name */ 224*7c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_mkey_name) 225*7c478bd9Sstevel@tonic-gate rdp->realm_mpname = strdup(rparams->realm_mkey_name); 226*7c478bd9Sstevel@tonic-gate else 227*7c478bd9Sstevel@tonic-gate rdp->realm_mpname = (def_mpname) ? strdup(def_mpname) : 228*7c478bd9Sstevel@tonic-gate strdup(KRB5_KDB_M_NAME); 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate /* Handle KDC ports */ 231*7c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_kdc_ports) 232*7c478bd9Sstevel@tonic-gate rdp->realm_ports = strdup(rparams->realm_kdc_ports); 233*7c478bd9Sstevel@tonic-gate else 234*7c478bd9Sstevel@tonic-gate rdp->realm_ports = strdup(def_udp_ports); 235*7c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_kdc_tcp_ports) 236*7c478bd9Sstevel@tonic-gate rdp->realm_tcp_ports = strdup(rparams->realm_kdc_tcp_ports); 237*7c478bd9Sstevel@tonic-gate else 238*7c478bd9Sstevel@tonic-gate rdp->realm_tcp_ports = strdup(def_tcp_ports); 239*7c478bd9Sstevel@tonic-gate 240*7c478bd9Sstevel@tonic-gate /* Handle stash file */ 241*7c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_stash_file) { 242*7c478bd9Sstevel@tonic-gate rdp->realm_stash = strdup(rparams->realm_stash_file); 243*7c478bd9Sstevel@tonic-gate manual = FALSE; 244*7c478bd9Sstevel@tonic-gate } else 245*7c478bd9Sstevel@tonic-gate manual = def_manual; 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate /* Handle master key type */ 248*7c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_enctype_valid) 249*7c478bd9Sstevel@tonic-gate rdp->realm_mkey.enctype = (krb5_enctype) rparams->realm_enctype; 250*7c478bd9Sstevel@tonic-gate else 251*7c478bd9Sstevel@tonic-gate rdp->realm_mkey.enctype = manual ? def_enctype : ENCTYPE_UNKNOWN; 252*7c478bd9Sstevel@tonic-gate if ((kret = krb5_timeofday(rdp->realm_context, &now))) { 253*7c478bd9Sstevel@tonic-gate com_err(progname, kret, gettext("while getting timeofday")); 254*7c478bd9Sstevel@tonic-gate goto whoops; 255*7c478bd9Sstevel@tonic-gate } 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate /* Handle ticket maximum life */ 258*7c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_max_life_valid) 259*7c478bd9Sstevel@tonic-gate rdp->realm_maxlife = rparams->realm_max_life; 260*7c478bd9Sstevel@tonic-gate else 261*7c478bd9Sstevel@tonic-gate rdp->realm_maxlife = KRB5_KDB_EXPIRATION - now - 3600; 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate /* Handle ticket renewable maximum life */ 264*7c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_max_rlife_valid) 265*7c478bd9Sstevel@tonic-gate rdp->realm_maxrlife = rparams->realm_max_rlife; 266*7c478bd9Sstevel@tonic-gate else 267*7c478bd9Sstevel@tonic-gate rdp->realm_maxrlife = KRB5_KDB_EXPIRATION - now - 3600; 268*7c478bd9Sstevel@tonic-gate 269*7c478bd9Sstevel@tonic-gate /* Handle key/salt list */ 270*7c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_num_keysalts) { 271*7c478bd9Sstevel@tonic-gate rdp->realm_kstypes = rparams->realm_keysalts; 272*7c478bd9Sstevel@tonic-gate rdp->realm_nkstypes = rparams->realm_num_keysalts; 273*7c478bd9Sstevel@tonic-gate rparams->realm_keysalts = NULL; 274*7c478bd9Sstevel@tonic-gate rparams->realm_num_keysalts = 0; 275*7c478bd9Sstevel@tonic-gate kslist = (krb5_key_salt_tuple *) rdp->realm_kstypes; 276*7c478bd9Sstevel@tonic-gate nkslist = rdp->realm_nkstypes; 277*7c478bd9Sstevel@tonic-gate } else { 278*7c478bd9Sstevel@tonic-gate /* 279*7c478bd9Sstevel@tonic-gate * XXX Initialize default key/salt list. 280*7c478bd9Sstevel@tonic-gate */ 281*7c478bd9Sstevel@tonic-gate if ((kslist = (krb5_key_salt_tuple *) 282*7c478bd9Sstevel@tonic-gate malloc(sizeof(krb5_key_salt_tuple)))) { 283*7c478bd9Sstevel@tonic-gate kslist->ks_enctype = ENCTYPE_DES_CBC_CRC; 284*7c478bd9Sstevel@tonic-gate kslist->ks_salttype = KRB5_KDB_SALTTYPE_NORMAL; 285*7c478bd9Sstevel@tonic-gate rdp->realm_kstypes = kslist; 286*7c478bd9Sstevel@tonic-gate rdp->realm_nkstypes = 1; 287*7c478bd9Sstevel@tonic-gate nkslist = 1; 288*7c478bd9Sstevel@tonic-gate } 289*7c478bd9Sstevel@tonic-gate else { 290*7c478bd9Sstevel@tonic-gate com_err(progname, ENOMEM, 291*7c478bd9Sstevel@tonic-gate gettext("while setting up key/salt list for realm %s"), 292*7c478bd9Sstevel@tonic-gate realm); 293*7c478bd9Sstevel@tonic-gate exit(1); 294*7c478bd9Sstevel@tonic-gate } 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate if (rparams) 298*7c478bd9Sstevel@tonic-gate krb5_free_realm_params(rdp->realm_context, rparams); 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate /* 301*7c478bd9Sstevel@tonic-gate * We've got our parameters, now go and setup our realm context. 302*7c478bd9Sstevel@tonic-gate */ 303*7c478bd9Sstevel@tonic-gate 304*7c478bd9Sstevel@tonic-gate /* Set the default realm of this context */ 305*7c478bd9Sstevel@tonic-gate if ((kret = krb5_set_default_realm(rdp->realm_context, realm))) { 306*7c478bd9Sstevel@tonic-gate com_err(progname, kret, gettext("while setting default realm to %s"), 307*7c478bd9Sstevel@tonic-gate realm); 308*7c478bd9Sstevel@tonic-gate goto whoops; 309*7c478bd9Sstevel@tonic-gate } 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate /* Assemble and parse the master key name */ 312*7c478bd9Sstevel@tonic-gate if ((kret = krb5_db_setup_mkey_name(rdp->realm_context, rdp->realm_mpname, 313*7c478bd9Sstevel@tonic-gate rdp->realm_name, (char **) NULL, 314*7c478bd9Sstevel@tonic-gate &rdp->realm_mprinc))) { 315*7c478bd9Sstevel@tonic-gate com_err(progname, kret, 316*7c478bd9Sstevel@tonic-gate gettext("while setting up master key name %s for realm %s"), 317*7c478bd9Sstevel@tonic-gate rdp->realm_mpname, realm); 318*7c478bd9Sstevel@tonic-gate goto whoops; 319*7c478bd9Sstevel@tonic-gate } 320*7c478bd9Sstevel@tonic-gate 321*7c478bd9Sstevel@tonic-gate /* 322*7c478bd9Sstevel@tonic-gate * Get the master key. 323*7c478bd9Sstevel@tonic-gate */ 324*7c478bd9Sstevel@tonic-gate if ((kret = krb5_db_fetch_mkey(rdp->realm_context, rdp->realm_mprinc, 325*7c478bd9Sstevel@tonic-gate rdp->realm_mkey.enctype, manual, 326*7c478bd9Sstevel@tonic-gate FALSE, rdp->realm_stash, 327*7c478bd9Sstevel@tonic-gate 0, &rdp->realm_mkey))) { 328*7c478bd9Sstevel@tonic-gate com_err(progname, kret, 329*7c478bd9Sstevel@tonic-gate gettext("while fetching master key %s for realm %s"), 330*7c478bd9Sstevel@tonic-gate rdp->realm_mpname, realm); 331*7c478bd9Sstevel@tonic-gate goto whoops; 332*7c478bd9Sstevel@tonic-gate } 333*7c478bd9Sstevel@tonic-gate 334*7c478bd9Sstevel@tonic-gate /* Set and open the database. */ 335*7c478bd9Sstevel@tonic-gate if (rdp->realm_dbname && 336*7c478bd9Sstevel@tonic-gate (kret = krb5_db_set_name(rdp->realm_context, rdp->realm_dbname))) { 337*7c478bd9Sstevel@tonic-gate com_err(progname, kret, 338*7c478bd9Sstevel@tonic-gate gettext("while setting database name to %s for realm %s"), 339*7c478bd9Sstevel@tonic-gate rdp->realm_dbname, realm); 340*7c478bd9Sstevel@tonic-gate goto whoops; 341*7c478bd9Sstevel@tonic-gate } 342*7c478bd9Sstevel@tonic-gate if ((kret = krb5_db_init(rdp->realm_context))) { 343*7c478bd9Sstevel@tonic-gate com_err(progname, kret, 344*7c478bd9Sstevel@tonic-gate gettext("while initializing database "), 345*7c478bd9Sstevel@tonic-gate gettext("for realm %s"), realm); 346*7c478bd9Sstevel@tonic-gate goto whoops; 347*7c478bd9Sstevel@tonic-gate } else 348*7c478bd9Sstevel@tonic-gate db_inited = 1; 349*7c478bd9Sstevel@tonic-gate 350*7c478bd9Sstevel@tonic-gate /* Verify the master key */ 351*7c478bd9Sstevel@tonic-gate if ((kret = krb5_db_verify_master_key(rdp->realm_context, 352*7c478bd9Sstevel@tonic-gate rdp->realm_mprinc, 353*7c478bd9Sstevel@tonic-gate &rdp->realm_mkey))) { 354*7c478bd9Sstevel@tonic-gate com_err(progname, kret, 355*7c478bd9Sstevel@tonic-gate gettext("while verifying master key for realm %s"), 356*7c478bd9Sstevel@tonic-gate realm); 357*7c478bd9Sstevel@tonic-gate goto whoops; 358*7c478bd9Sstevel@tonic-gate } 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gate /* Fetch the master key and get its version number */ 361*7c478bd9Sstevel@tonic-gate num2get = 1; 362*7c478bd9Sstevel@tonic-gate kret = krb5_db_get_principal(rdp->realm_context, rdp->realm_mprinc, 363*7c478bd9Sstevel@tonic-gate &db_entry, &num2get, &more); 364*7c478bd9Sstevel@tonic-gate if (!kret) { 365*7c478bd9Sstevel@tonic-gate if (num2get != 1) 366*7c478bd9Sstevel@tonic-gate kret = KRB5_KDB_NOMASTERKEY; 367*7c478bd9Sstevel@tonic-gate else { 368*7c478bd9Sstevel@tonic-gate if (more) { 369*7c478bd9Sstevel@tonic-gate krb5_db_free_principal(rdp->realm_context, 370*7c478bd9Sstevel@tonic-gate &db_entry, 371*7c478bd9Sstevel@tonic-gate num2get); 372*7c478bd9Sstevel@tonic-gate kret = KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE; 373*7c478bd9Sstevel@tonic-gate } 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate } 376*7c478bd9Sstevel@tonic-gate if (kret) { 377*7c478bd9Sstevel@tonic-gate com_err(progname, kret, 378*7c478bd9Sstevel@tonic-gate gettext("while fetching master entry for realm %s"), 379*7c478bd9Sstevel@tonic-gate realm); 380*7c478bd9Sstevel@tonic-gate goto whoops; 381*7c478bd9Sstevel@tonic-gate } 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate /* 384*7c478bd9Sstevel@tonic-gate * Get the most recent master key. Search the key list in 385*7c478bd9Sstevel@tonic-gate * the order specified by the key/salt list. 386*7c478bd9Sstevel@tonic-gate */ 387*7c478bd9Sstevel@tonic-gate kdata = (krb5_key_data *) NULL; 388*7c478bd9Sstevel@tonic-gate for (i=0; i<nkslist; i++) { 389*7c478bd9Sstevel@tonic-gate if (!(kret = krb5_dbe_find_enctype(rdp->realm_context, 390*7c478bd9Sstevel@tonic-gate &db_entry, 391*7c478bd9Sstevel@tonic-gate kslist[i].ks_enctype, 392*7c478bd9Sstevel@tonic-gate -1, 393*7c478bd9Sstevel@tonic-gate -1, 394*7c478bd9Sstevel@tonic-gate &kdata))) 395*7c478bd9Sstevel@tonic-gate break; 396*7c478bd9Sstevel@tonic-gate } 397*7c478bd9Sstevel@tonic-gate if (!kdata) { 398*7c478bd9Sstevel@tonic-gate com_err(progname, kret, 399*7c478bd9Sstevel@tonic-gate gettext("while finding master key for realm %s"), 400*7c478bd9Sstevel@tonic-gate realm); 401*7c478bd9Sstevel@tonic-gate goto whoops; 402*7c478bd9Sstevel@tonic-gate } 403*7c478bd9Sstevel@tonic-gate rdp->realm_mkvno = kdata->key_data_kvno; 404*7c478bd9Sstevel@tonic-gate krb5_db_free_principal(rdp->realm_context, &db_entry, num2get); 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate if ((kret = krb5_db_set_mkey(rdp->realm_context, &rdp->realm_mkey))) { 407*7c478bd9Sstevel@tonic-gate com_err(progname, kret, 408*7c478bd9Sstevel@tonic-gate gettext("while processing master key for realm %s"), 409*7c478bd9Sstevel@tonic-gate realm); 410*7c478bd9Sstevel@tonic-gate goto whoops; 411*7c478bd9Sstevel@tonic-gate } 412*7c478bd9Sstevel@tonic-gate 413*7c478bd9Sstevel@tonic-gate /* Set up the keytab */ 414*7c478bd9Sstevel@tonic-gate if ((kret = krb5_ktkdb_resolve(rdp->realm_context, 415*7c478bd9Sstevel@tonic-gate NULL, 416*7c478bd9Sstevel@tonic-gate &rdp->realm_keytab))) { 417*7c478bd9Sstevel@tonic-gate com_err(progname, kret, 418*7c478bd9Sstevel@tonic-gate gettext("while resolving kdb keytab for realm %s"), 419*7c478bd9Sstevel@tonic-gate realm); 420*7c478bd9Sstevel@tonic-gate goto whoops; 421*7c478bd9Sstevel@tonic-gate } 422*7c478bd9Sstevel@tonic-gate 423*7c478bd9Sstevel@tonic-gate /* Preformat the TGS name */ 424*7c478bd9Sstevel@tonic-gate if ((kret = krb5_build_principal(rdp->realm_context, &rdp->realm_tgsprinc, 425*7c478bd9Sstevel@tonic-gate strlen(realm), realm, KRB5_TGS_NAME, 426*7c478bd9Sstevel@tonic-gate realm, (char *) NULL))) { 427*7c478bd9Sstevel@tonic-gate com_err(progname, kret, 428*7c478bd9Sstevel@tonic-gate gettext("while building TGS name for realm %s"), 429*7c478bd9Sstevel@tonic-gate realm); 430*7c478bd9Sstevel@tonic-gate goto whoops; 431*7c478bd9Sstevel@tonic-gate } 432*7c478bd9Sstevel@tonic-gate 433*7c478bd9Sstevel@tonic-gate /* Get the TGS database entry */ 434*7c478bd9Sstevel@tonic-gate num2get = 1; 435*7c478bd9Sstevel@tonic-gate if (!(kret = krb5_db_get_principal(rdp->realm_context, 436*7c478bd9Sstevel@tonic-gate rdp->realm_tgsprinc, 437*7c478bd9Sstevel@tonic-gate &db_entry, 438*7c478bd9Sstevel@tonic-gate &num2get, 439*7c478bd9Sstevel@tonic-gate &more))) { 440*7c478bd9Sstevel@tonic-gate if (num2get != 1) 441*7c478bd9Sstevel@tonic-gate kret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; 442*7c478bd9Sstevel@tonic-gate else { 443*7c478bd9Sstevel@tonic-gate if (more) { 444*7c478bd9Sstevel@tonic-gate krb5_db_free_principal(rdp->realm_context, 445*7c478bd9Sstevel@tonic-gate &db_entry, 446*7c478bd9Sstevel@tonic-gate num2get); 447*7c478bd9Sstevel@tonic-gate kret = KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE; 448*7c478bd9Sstevel@tonic-gate } 449*7c478bd9Sstevel@tonic-gate } 450*7c478bd9Sstevel@tonic-gate } 451*7c478bd9Sstevel@tonic-gate if (kret) { 452*7c478bd9Sstevel@tonic-gate com_err(progname, kret, 453*7c478bd9Sstevel@tonic-gate gettext("while fetching TGS entry for realm %s"), 454*7c478bd9Sstevel@tonic-gate realm); 455*7c478bd9Sstevel@tonic-gate goto whoops; 456*7c478bd9Sstevel@tonic-gate } 457*7c478bd9Sstevel@tonic-gate /* 458*7c478bd9Sstevel@tonic-gate * Get the most recent TGS key. Search the key list in 459*7c478bd9Sstevel@tonic-gate * the order specified by the key/salt list. 460*7c478bd9Sstevel@tonic-gate */ 461*7c478bd9Sstevel@tonic-gate kdata = (krb5_key_data *) NULL; 462*7c478bd9Sstevel@tonic-gate for (i=0; i<nkslist; i++) { 463*7c478bd9Sstevel@tonic-gate if (!(kret = krb5_dbe_find_enctype(rdp->realm_context, 464*7c478bd9Sstevel@tonic-gate &db_entry, 465*7c478bd9Sstevel@tonic-gate kslist[i].ks_enctype, 466*7c478bd9Sstevel@tonic-gate -1, 467*7c478bd9Sstevel@tonic-gate -1, 468*7c478bd9Sstevel@tonic-gate &kdata))) 469*7c478bd9Sstevel@tonic-gate break; 470*7c478bd9Sstevel@tonic-gate } 471*7c478bd9Sstevel@tonic-gate if (!kdata) { 472*7c478bd9Sstevel@tonic-gate com_err(progname, kret, 473*7c478bd9Sstevel@tonic-gate gettext("while finding TGS key for realm %s"), 474*7c478bd9Sstevel@tonic-gate realm); 475*7c478bd9Sstevel@tonic-gate goto whoops; 476*7c478bd9Sstevel@tonic-gate } 477*7c478bd9Sstevel@tonic-gate if (!(kret = krb5_dbekd_decrypt_key_data(rdp->realm_context, 478*7c478bd9Sstevel@tonic-gate &rdp->realm_mkey, 479*7c478bd9Sstevel@tonic-gate kdata, 480*7c478bd9Sstevel@tonic-gate &rdp->realm_tgskey, NULL))){ 481*7c478bd9Sstevel@tonic-gate rdp->realm_tgskvno = kdata->key_data_kvno; 482*7c478bd9Sstevel@tonic-gate } 483*7c478bd9Sstevel@tonic-gate krb5_db_free_principal(rdp->realm_context, 484*7c478bd9Sstevel@tonic-gate &db_entry, 485*7c478bd9Sstevel@tonic-gate num2get); 486*7c478bd9Sstevel@tonic-gate if (kret) { 487*7c478bd9Sstevel@tonic-gate com_err(progname, kret, 488*7c478bd9Sstevel@tonic-gate gettext("while decrypting TGS key for realm %s"), 489*7c478bd9Sstevel@tonic-gate realm); 490*7c478bd9Sstevel@tonic-gate goto whoops; 491*7c478bd9Sstevel@tonic-gate } 492*7c478bd9Sstevel@tonic-gate 493*7c478bd9Sstevel@tonic-gate if (!rkey_init_done) { 494*7c478bd9Sstevel@tonic-gate krb5_timestamp now; 495*7c478bd9Sstevel@tonic-gate krb5_data seed; 496*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 497*7c478bd9Sstevel@tonic-gate krb5_keyblock temp_key; 498*7c478bd9Sstevel@tonic-gate #endif 499*7c478bd9Sstevel@tonic-gate /* 500*7c478bd9Sstevel@tonic-gate * If all that worked, then initialize the random key 501*7c478bd9Sstevel@tonic-gate * generators. 502*7c478bd9Sstevel@tonic-gate */ 503*7c478bd9Sstevel@tonic-gate 504*7c478bd9Sstevel@tonic-gate if ((kret = krb5_timeofday(rdp->realm_context, &now))) 505*7c478bd9Sstevel@tonic-gate goto whoops; 506*7c478bd9Sstevel@tonic-gate seed.length = sizeof(now); 507*7c478bd9Sstevel@tonic-gate seed.data = (char *) &now; 508*7c478bd9Sstevel@tonic-gate if ((kret = krb5_c_random_seed(rdp->realm_context, &seed))) 509*7c478bd9Sstevel@tonic-gate goto whoops; 510*7c478bd9Sstevel@tonic-gate 511*7c478bd9Sstevel@tonic-gate seed.length = rdp->realm_mkey.length; 512*7c478bd9Sstevel@tonic-gate seed.data = (char *)rdp->realm_mkey.contents; 513*7c478bd9Sstevel@tonic-gate 514*7c478bd9Sstevel@tonic-gate if ((kret = krb5_c_random_seed(rdp->realm_context, &seed))) 515*7c478bd9Sstevel@tonic-gate goto whoops; 516*7c478bd9Sstevel@tonic-gate 517*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 518*7c478bd9Sstevel@tonic-gate if ((kret = krb5_c_make_random_key(rdp->realm_context, 519*7c478bd9Sstevel@tonic-gate ENCTYPE_DES_CBC_CRC, &temp_key))) { 520*7c478bd9Sstevel@tonic-gate com_err(progname, kret, 521*7c478bd9Sstevel@tonic-gate "while initializing V4 random key generator"); 522*7c478bd9Sstevel@tonic-gate goto whoops; 523*7c478bd9Sstevel@tonic-gate } 524*7c478bd9Sstevel@tonic-gate 525*7c478bd9Sstevel@tonic-gate (void) des_init_random_number_generator(temp_key.contents); 526*7c478bd9Sstevel@tonic-gate krb5_free_keyblock_contents(rdp->realm_context, &temp_key); 527*7c478bd9Sstevel@tonic-gate #endif 528*7c478bd9Sstevel@tonic-gate rkey_init_done = 1; 529*7c478bd9Sstevel@tonic-gate } 530*7c478bd9Sstevel@tonic-gate whoops: 531*7c478bd9Sstevel@tonic-gate /* 532*7c478bd9Sstevel@tonic-gate * If we choked, then clean up any dirt we may have dropped on the floor. 533*7c478bd9Sstevel@tonic-gate */ 534*7c478bd9Sstevel@tonic-gate if (kret) { 535*7c478bd9Sstevel@tonic-gate finish_realm(rdp); 536*7c478bd9Sstevel@tonic-gate } 537*7c478bd9Sstevel@tonic-gate return(kret); 538*7c478bd9Sstevel@tonic-gate } 539*7c478bd9Sstevel@tonic-gate 540*7c478bd9Sstevel@tonic-gate krb5_sigtype 541*7c478bd9Sstevel@tonic-gate request_exit(signo) 542*7c478bd9Sstevel@tonic-gate int signo; 543*7c478bd9Sstevel@tonic-gate { 544*7c478bd9Sstevel@tonic-gate signal_requests_exit = 1; 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGTYPE 547*7c478bd9Sstevel@tonic-gate return; 548*7c478bd9Sstevel@tonic-gate #else 549*7c478bd9Sstevel@tonic-gate return(0); 550*7c478bd9Sstevel@tonic-gate #endif 551*7c478bd9Sstevel@tonic-gate } 552*7c478bd9Sstevel@tonic-gate 553*7c478bd9Sstevel@tonic-gate krb5_sigtype 554*7c478bd9Sstevel@tonic-gate request_hup(signo) 555*7c478bd9Sstevel@tonic-gate int signo; 556*7c478bd9Sstevel@tonic-gate { 557*7c478bd9Sstevel@tonic-gate signal_requests_hup = 1; 558*7c478bd9Sstevel@tonic-gate 559*7c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGTYPE 560*7c478bd9Sstevel@tonic-gate return; 561*7c478bd9Sstevel@tonic-gate #else 562*7c478bd9Sstevel@tonic-gate return(0); 563*7c478bd9Sstevel@tonic-gate #endif 564*7c478bd9Sstevel@tonic-gate } 565*7c478bd9Sstevel@tonic-gate 566*7c478bd9Sstevel@tonic-gate void 567*7c478bd9Sstevel@tonic-gate setup_signal_handlers() 568*7c478bd9Sstevel@tonic-gate { 569*7c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGNALS 570*7c478bd9Sstevel@tonic-gate (void) sigemptyset(&s_action.sa_mask); 571*7c478bd9Sstevel@tonic-gate s_action.sa_flags = 0; 572*7c478bd9Sstevel@tonic-gate s_action.sa_handler = request_exit; 573*7c478bd9Sstevel@tonic-gate (void) sigaction(SIGINT, &s_action, (struct sigaction *) NULL); 574*7c478bd9Sstevel@tonic-gate (void) sigaction(SIGTERM, &s_action, (struct sigaction *) NULL); 575*7c478bd9Sstevel@tonic-gate s_action.sa_handler = request_hup; 576*7c478bd9Sstevel@tonic-gate (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL); 577*7c478bd9Sstevel@tonic-gate #else /* POSIX_SIGNALS */ 578*7c478bd9Sstevel@tonic-gate signal(SIGINT, request_exit); 579*7c478bd9Sstevel@tonic-gate signal(SIGTERM, request_exit); 580*7c478bd9Sstevel@tonic-gate signal(SIGHUP, request_hup); 581*7c478bd9Sstevel@tonic-gate #endif /* POSIX_SIGNALS */ 582*7c478bd9Sstevel@tonic-gate 583*7c478bd9Sstevel@tonic-gate return; 584*7c478bd9Sstevel@tonic-gate } 585*7c478bd9Sstevel@tonic-gate 586*7c478bd9Sstevel@tonic-gate krb5_error_code 587*7c478bd9Sstevel@tonic-gate setup_sam() 588*7c478bd9Sstevel@tonic-gate { 589*7c478bd9Sstevel@tonic-gate return krb5_c_make_random_key(kdc_context, ENCTYPE_DES_CBC_MD5, &psr_key); 590*7c478bd9Sstevel@tonic-gate } 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate void 593*7c478bd9Sstevel@tonic-gate usage(name) 594*7c478bd9Sstevel@tonic-gate char *name; 595*7c478bd9Sstevel@tonic-gate { 596*7c478bd9Sstevel@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); 597*7c478bd9Sstevel@tonic-gate return; 598*7c478bd9Sstevel@tonic-gate } 599*7c478bd9Sstevel@tonic-gate 600*7c478bd9Sstevel@tonic-gate void 601*7c478bd9Sstevel@tonic-gate initialize_realms(kcontext, argc, argv) 602*7c478bd9Sstevel@tonic-gate krb5_context kcontext; 603*7c478bd9Sstevel@tonic-gate int argc; 604*7c478bd9Sstevel@tonic-gate char **argv; 605*7c478bd9Sstevel@tonic-gate { 606*7c478bd9Sstevel@tonic-gate int c; 607*7c478bd9Sstevel@tonic-gate char *db_name = (char *) NULL; 608*7c478bd9Sstevel@tonic-gate char *mkey_name = (char *) NULL; 609*7c478bd9Sstevel@tonic-gate char *rcname = KDCRCACHE; 610*7c478bd9Sstevel@tonic-gate char *lrealm; 611*7c478bd9Sstevel@tonic-gate krb5_error_code retval; 612*7c478bd9Sstevel@tonic-gate krb5_enctype menctype = ENCTYPE_UNKNOWN; 613*7c478bd9Sstevel@tonic-gate kdc_realm_t *rdatap; 614*7c478bd9Sstevel@tonic-gate krb5_boolean manual = FALSE; 615*7c478bd9Sstevel@tonic-gate char *default_udp_ports = 0; 616*7c478bd9Sstevel@tonic-gate char *default_tcp_ports = 0; 617*7c478bd9Sstevel@tonic-gate krb5_pointer aprof; 618*7c478bd9Sstevel@tonic-gate const char *hierarchy[3]; 619*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 620*7c478bd9Sstevel@tonic-gate char *v4mode = 0; 621*7c478bd9Sstevel@tonic-gate #endif 622*7c478bd9Sstevel@tonic-gate extern char *optarg; 623*7c478bd9Sstevel@tonic-gate #ifdef ATHENA_DES3_KLUDGE 624*7c478bd9Sstevel@tonic-gate extern struct krb5_keytypes krb5_enctypes_list[]; 625*7c478bd9Sstevel@tonic-gate extern int krb5_enctypes_length; 626*7c478bd9Sstevel@tonic-gate #endif 627*7c478bd9Sstevel@tonic-gate 628*7c478bd9Sstevel@tonic-gate if (!krb5_aprof_init(DEFAULT_KDC_PROFILE, KDC_PROFILE_ENV, &aprof)) { 629*7c478bd9Sstevel@tonic-gate hierarchy[0] = "kdcdefaults"; 630*7c478bd9Sstevel@tonic-gate hierarchy[1] = "kdc_ports"; 631*7c478bd9Sstevel@tonic-gate hierarchy[2] = (char *) NULL; 632*7c478bd9Sstevel@tonic-gate if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_udp_ports)) 633*7c478bd9Sstevel@tonic-gate default_udp_ports = 0; 634*7c478bd9Sstevel@tonic-gate hierarchy[1] = "kdc_tcp_ports"; 635*7c478bd9Sstevel@tonic-gate if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_tcp_ports)) 636*7c478bd9Sstevel@tonic-gate default_tcp_ports = 0; 637*7c478bd9Sstevel@tonic-gate hierarchy[1] = "kdc_max_tcp_connections"; 638*7c478bd9Sstevel@tonic-gate if (krb5_aprof_get_int32(aprof, hierarchy, TRUE, 639*7c478bd9Sstevel@tonic-gate &max_tcp_data_connections)) { 640*7c478bd9Sstevel@tonic-gate max_tcp_data_connections = DEFAULT_KDC_TCP_CONNECTIONS; 641*7c478bd9Sstevel@tonic-gate } else if (max_tcp_data_connections < MIN_KDC_TCP_CONNECTIONS) { 642*7c478bd9Sstevel@tonic-gate max_tcp_data_connections = DEFAULT_KDC_TCP_CONNECTIONS; 643*7c478bd9Sstevel@tonic-gate } 644*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 645*7c478bd9Sstevel@tonic-gate hierarchy[1] = "v4_mode"; 646*7c478bd9Sstevel@tonic-gate if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &v4mode)) 647*7c478bd9Sstevel@tonic-gate v4mode = 0; 648*7c478bd9Sstevel@tonic-gate #endif 649*7c478bd9Sstevel@tonic-gate /* aprof_init can return 0 with aprof == NULL */ 650*7c478bd9Sstevel@tonic-gate if (aprof) 651*7c478bd9Sstevel@tonic-gate krb5_aprof_finish(aprof); 652*7c478bd9Sstevel@tonic-gate } 653*7c478bd9Sstevel@tonic-gate if (default_udp_ports == 0) 654*7c478bd9Sstevel@tonic-gate default_udp_ports = strdup(DEFAULT_KDC_UDP_PORTLIST); 655*7c478bd9Sstevel@tonic-gate if (default_tcp_ports == 0) 656*7c478bd9Sstevel@tonic-gate default_tcp_ports = strdup(DEFAULT_KDC_TCP_PORTLIST); 657*7c478bd9Sstevel@tonic-gate /* 658*7c478bd9Sstevel@tonic-gate * Loop through the option list. Each time we encounter a realm name, 659*7c478bd9Sstevel@tonic-gate * use the previously scanned options to fill in for defaults. 660*7c478bd9Sstevel@tonic-gate */ 661*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "r:d:mM:k:R:e:p:s:n")) != -1) { /* SUNW */ 662*7c478bd9Sstevel@tonic-gate switch(c) { 663*7c478bd9Sstevel@tonic-gate case 'r': /* realm name for db */ 664*7c478bd9Sstevel@tonic-gate if (!find_realm_data(optarg, (krb5_ui_4) strlen(optarg))) { 665*7c478bd9Sstevel@tonic-gate if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) { 666*7c478bd9Sstevel@tonic-gate if ((retval = init_realm(argv[0], rdatap, optarg, db_name, 667*7c478bd9Sstevel@tonic-gate mkey_name, menctype, 668*7c478bd9Sstevel@tonic-gate default_udp_ports, 669*7c478bd9Sstevel@tonic-gate default_tcp_ports, manual))) { 670*7c478bd9Sstevel@tonic-gate fprintf(stderr,gettext("%s: cannot initialize realm %s\n"), 671*7c478bd9Sstevel@tonic-gate argv[0], optarg); 672*7c478bd9Sstevel@tonic-gate exit(1); 673*7c478bd9Sstevel@tonic-gate } 674*7c478bd9Sstevel@tonic-gate kdc_realmlist[kdc_numrealms] = rdatap; 675*7c478bd9Sstevel@tonic-gate kdc_numrealms++; 676*7c478bd9Sstevel@tonic-gate } 677*7c478bd9Sstevel@tonic-gate } 678*7c478bd9Sstevel@tonic-gate break; 679*7c478bd9Sstevel@tonic-gate case 'd': /* pathname for db */ 680*7c478bd9Sstevel@tonic-gate db_name = optarg; 681*7c478bd9Sstevel@tonic-gate break; 682*7c478bd9Sstevel@tonic-gate case 'm': /* manual type-in of master key */ 683*7c478bd9Sstevel@tonic-gate manual = TRUE; 684*7c478bd9Sstevel@tonic-gate if (menctype == ENCTYPE_UNKNOWN) 685*7c478bd9Sstevel@tonic-gate menctype = ENCTYPE_DES_CBC_CRC; 686*7c478bd9Sstevel@tonic-gate break; 687*7c478bd9Sstevel@tonic-gate case 'M': /* master key name in DB */ 688*7c478bd9Sstevel@tonic-gate mkey_name = optarg; 689*7c478bd9Sstevel@tonic-gate break; 690*7c478bd9Sstevel@tonic-gate case 'n': 691*7c478bd9Sstevel@tonic-gate nofork++; /* don't detach from terminal */ 692*7c478bd9Sstevel@tonic-gate break; 693*7c478bd9Sstevel@tonic-gate case 'k': /* enctype for master key */ 694*7c478bd9Sstevel@tonic-gate if (krb5_string_to_enctype(optarg, &menctype)) 695*7c478bd9Sstevel@tonic-gate com_err(argv[0], 0, 696*7c478bd9Sstevel@tonic-gate gettext("invalid enctype %s"), optarg); 697*7c478bd9Sstevel@tonic-gate break; 698*7c478bd9Sstevel@tonic-gate case 'R': 699*7c478bd9Sstevel@tonic-gate rcname = optarg; 700*7c478bd9Sstevel@tonic-gate break; 701*7c478bd9Sstevel@tonic-gate case 'p': 702*7c478bd9Sstevel@tonic-gate if (default_udp_ports) 703*7c478bd9Sstevel@tonic-gate free(default_udp_ports); 704*7c478bd9Sstevel@tonic-gate default_udp_ports = strdup(optarg); 705*7c478bd9Sstevel@tonic-gate 706*7c478bd9Sstevel@tonic-gate if (default_tcp_ports) 707*7c478bd9Sstevel@tonic-gate free(default_tcp_ports); 708*7c478bd9Sstevel@tonic-gate default_tcp_ports = strdup(optarg); 709*7c478bd9Sstevel@tonic-gate 710*7c478bd9Sstevel@tonic-gate break; 711*7c478bd9Sstevel@tonic-gate case '4': 712*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 713*7c478bd9Sstevel@tonic-gate if (v4mode) 714*7c478bd9Sstevel@tonic-gate free(v4mode); 715*7c478bd9Sstevel@tonic-gate v4mode = strdup(optarg); 716*7c478bd9Sstevel@tonic-gate #endif 717*7c478bd9Sstevel@tonic-gate break; 718*7c478bd9Sstevel@tonic-gate case '3': 719*7c478bd9Sstevel@tonic-gate #ifdef ATHENA_DES3_KLUDGE 720*7c478bd9Sstevel@tonic-gate if (krb5_enctypes_list[krb5_enctypes_length-1].etype 721*7c478bd9Sstevel@tonic-gate != ENCTYPE_LOCAL_DES3_HMAC_SHA1) { 722*7c478bd9Sstevel@tonic-gate fprintf(stderr, 723*7c478bd9Sstevel@tonic-gate "internal inconsistency in enctypes_list" 724*7c478bd9Sstevel@tonic-gate " while disabling\n" 725*7c478bd9Sstevel@tonic-gate "des3-marc-hmac-sha1 enctype\n"); 726*7c478bd9Sstevel@tonic-gate exit(1); 727*7c478bd9Sstevel@tonic-gate } 728*7c478bd9Sstevel@tonic-gate krb5_enctypes_length--; 729*7c478bd9Sstevel@tonic-gate break; 730*7c478bd9Sstevel@tonic-gate #endif 731*7c478bd9Sstevel@tonic-gate case '?': 732*7c478bd9Sstevel@tonic-gate default: 733*7c478bd9Sstevel@tonic-gate usage(argv[0]); 734*7c478bd9Sstevel@tonic-gate exit(1); 735*7c478bd9Sstevel@tonic-gate } 736*7c478bd9Sstevel@tonic-gate } 737*7c478bd9Sstevel@tonic-gate 738*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 739*7c478bd9Sstevel@tonic-gate /* 740*7c478bd9Sstevel@tonic-gate * Setup the v4 mode 741*7c478bd9Sstevel@tonic-gate */ 742*7c478bd9Sstevel@tonic-gate process_v4_mode(argv[0], v4mode); 743*7c478bd9Sstevel@tonic-gate #endif 744*7c478bd9Sstevel@tonic-gate 745*7c478bd9Sstevel@tonic-gate /* 746*7c478bd9Sstevel@tonic-gate * Check to see if we processed any realms. 747*7c478bd9Sstevel@tonic-gate */ 748*7c478bd9Sstevel@tonic-gate if (kdc_numrealms == 0) { 749*7c478bd9Sstevel@tonic-gate /* no realm specified, use default realm */ 750*7c478bd9Sstevel@tonic-gate if ((retval = krb5_get_default_realm(kcontext, &lrealm))) { 751*7c478bd9Sstevel@tonic-gate com_err(argv[0], retval, 752*7c478bd9Sstevel@tonic-gate gettext("while attempting to retrieve default realm")); 753*7c478bd9Sstevel@tonic-gate exit(1); 754*7c478bd9Sstevel@tonic-gate } 755*7c478bd9Sstevel@tonic-gate if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) { 756*7c478bd9Sstevel@tonic-gate if ((retval = init_realm(argv[0], rdatap, lrealm, db_name, 757*7c478bd9Sstevel@tonic-gate mkey_name, menctype, default_udp_ports, 758*7c478bd9Sstevel@tonic-gate default_tcp_ports, manual))) { 759*7c478bd9Sstevel@tonic-gate fprintf(stderr, 760*7c478bd9Sstevel@tonic-gate gettext("%s: cannot initialize realm %s\n"), 761*7c478bd9Sstevel@tonic-gate argv[0], lrealm); 762*7c478bd9Sstevel@tonic-gate exit(1); 763*7c478bd9Sstevel@tonic-gate } 764*7c478bd9Sstevel@tonic-gate kdc_realmlist[0] = rdatap; 765*7c478bd9Sstevel@tonic-gate kdc_numrealms++; 766*7c478bd9Sstevel@tonic-gate } 767*7c478bd9Sstevel@tonic-gate } 768*7c478bd9Sstevel@tonic-gate 769*7c478bd9Sstevel@tonic-gate #ifdef USE_RCACHE 770*7c478bd9Sstevel@tonic-gate /* 771*7c478bd9Sstevel@tonic-gate * Now handle the replay cache. 772*7c478bd9Sstevel@tonic-gate */ 773*7c478bd9Sstevel@tonic-gate if ((retval = kdc_initialize_rcache(kcontext, rcname))) { 774*7c478bd9Sstevel@tonic-gate com_err(argv[0], retval, gettext("while initializing KDC replay cache")); 775*7c478bd9Sstevel@tonic-gate exit(1); 776*7c478bd9Sstevel@tonic-gate } 777*7c478bd9Sstevel@tonic-gate #endif 778*7c478bd9Sstevel@tonic-gate 779*7c478bd9Sstevel@tonic-gate /* Ensure that this is set for our first request. */ 780*7c478bd9Sstevel@tonic-gate kdc_active_realm = kdc_realmlist[0]; 781*7c478bd9Sstevel@tonic-gate if (default_udp_ports) 782*7c478bd9Sstevel@tonic-gate free(default_udp_ports); 783*7c478bd9Sstevel@tonic-gate if (default_tcp_ports) 784*7c478bd9Sstevel@tonic-gate free(default_tcp_ports); 785*7c478bd9Sstevel@tonic-gate 786*7c478bd9Sstevel@tonic-gate return; 787*7c478bd9Sstevel@tonic-gate } 788*7c478bd9Sstevel@tonic-gate 789*7c478bd9Sstevel@tonic-gate void 790*7c478bd9Sstevel@tonic-gate finish_realms(prog) 791*7c478bd9Sstevel@tonic-gate char *prog; 792*7c478bd9Sstevel@tonic-gate { 793*7c478bd9Sstevel@tonic-gate int i; 794*7c478bd9Sstevel@tonic-gate 795*7c478bd9Sstevel@tonic-gate for (i = 0; i < kdc_numrealms; i++) { 796*7c478bd9Sstevel@tonic-gate finish_realm(kdc_realmlist[i]); 797*7c478bd9Sstevel@tonic-gate kdc_realmlist[i] = 0; 798*7c478bd9Sstevel@tonic-gate } 799*7c478bd9Sstevel@tonic-gate } 800*7c478bd9Sstevel@tonic-gate 801*7c478bd9Sstevel@tonic-gate /* 802*7c478bd9Sstevel@tonic-gate outline: 803*7c478bd9Sstevel@tonic-gate 804*7c478bd9Sstevel@tonic-gate process args & setup 805*7c478bd9Sstevel@tonic-gate 806*7c478bd9Sstevel@tonic-gate initialize database access (fetch master key, open DB) 807*7c478bd9Sstevel@tonic-gate 808*7c478bd9Sstevel@tonic-gate initialize network 809*7c478bd9Sstevel@tonic-gate 810*7c478bd9Sstevel@tonic-gate loop: 811*7c478bd9Sstevel@tonic-gate listen for packet 812*7c478bd9Sstevel@tonic-gate 813*7c478bd9Sstevel@tonic-gate determine packet type, dispatch to handling routine 814*7c478bd9Sstevel@tonic-gate (AS or TGS (or V4?)) 815*7c478bd9Sstevel@tonic-gate 816*7c478bd9Sstevel@tonic-gate reflect response 817*7c478bd9Sstevel@tonic-gate 818*7c478bd9Sstevel@tonic-gate exit on signal 819*7c478bd9Sstevel@tonic-gate 820*7c478bd9Sstevel@tonic-gate clean up secrets, close db 821*7c478bd9Sstevel@tonic-gate 822*7c478bd9Sstevel@tonic-gate shut down network 823*7c478bd9Sstevel@tonic-gate 824*7c478bd9Sstevel@tonic-gate exit 825*7c478bd9Sstevel@tonic-gate */ 826*7c478bd9Sstevel@tonic-gate 827*7c478bd9Sstevel@tonic-gate int main(argc, argv) 828*7c478bd9Sstevel@tonic-gate int argc; 829*7c478bd9Sstevel@tonic-gate char *argv[]; 830*7c478bd9Sstevel@tonic-gate { 831*7c478bd9Sstevel@tonic-gate krb5_error_code retval; 832*7c478bd9Sstevel@tonic-gate krb5_context kcontext; 833*7c478bd9Sstevel@tonic-gate int *port_list; 834*7c478bd9Sstevel@tonic-gate int errout = 0; 835*7c478bd9Sstevel@tonic-gate 836*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 837*7c478bd9Sstevel@tonic-gate 838*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 839*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "KRB5KDC_TEST" /* Use this only if it weren't */ 840*7c478bd9Sstevel@tonic-gate #endif 841*7c478bd9Sstevel@tonic-gate 842*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 843*7c478bd9Sstevel@tonic-gate 844*7c478bd9Sstevel@tonic-gate if (strrchr(argv[0], '/')) 845*7c478bd9Sstevel@tonic-gate argv[0] = strrchr(argv[0], '/')+1; 846*7c478bd9Sstevel@tonic-gate 847*7c478bd9Sstevel@tonic-gate if (!(kdc_realmlist = (kdc_realm_t **) malloc(sizeof(kdc_realm_t *) * 848*7c478bd9Sstevel@tonic-gate KRB5_KDC_MAX_REALMS))) { 849*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: cannot get memory for realm list\n"), argv[0]); 850*7c478bd9Sstevel@tonic-gate exit(1); 851*7c478bd9Sstevel@tonic-gate } 852*7c478bd9Sstevel@tonic-gate memset((char *) kdc_realmlist, 0, 853*7c478bd9Sstevel@tonic-gate (size_t) (sizeof(kdc_realm_t *) * KRB5_KDC_MAX_REALMS)); 854*7c478bd9Sstevel@tonic-gate port_list = NULL; 855*7c478bd9Sstevel@tonic-gate 856*7c478bd9Sstevel@tonic-gate /* 857*7c478bd9Sstevel@tonic-gate * A note about Kerberos contexts: This context, "kcontext", is used 858*7c478bd9Sstevel@tonic-gate * for the KDC operations, i.e. setup, network connection and error 859*7c478bd9Sstevel@tonic-gate * reporting. The per-realm operations use the "realm_context" 860*7c478bd9Sstevel@tonic-gate * associated with each realm. 861*7c478bd9Sstevel@tonic-gate */ 862*7c478bd9Sstevel@tonic-gate retval = krb5_init_context(&kcontext); 863*7c478bd9Sstevel@tonic-gate if (retval) { 864*7c478bd9Sstevel@tonic-gate com_err(argv[0], retval, gettext("while initializing krb5")); 865*7c478bd9Sstevel@tonic-gate exit(1); 866*7c478bd9Sstevel@tonic-gate } 867*7c478bd9Sstevel@tonic-gate krb5_klog_init(kcontext, "kdc", argv[0], 1); 868*7c478bd9Sstevel@tonic-gate /* initialize_kdc5_error_table(); SUNWresync121 XXX */ 869*7c478bd9Sstevel@tonic-gate 870*7c478bd9Sstevel@tonic-gate /* 871*7c478bd9Sstevel@tonic-gate * Scan through the argument list 872*7c478bd9Sstevel@tonic-gate */ 873*7c478bd9Sstevel@tonic-gate initialize_realms(kcontext, argc, argv); 874*7c478bd9Sstevel@tonic-gate 875*7c478bd9Sstevel@tonic-gate setup_signal_handlers(); 876*7c478bd9Sstevel@tonic-gate 877*7c478bd9Sstevel@tonic-gate if (retval = setup_sam()) { 878*7c478bd9Sstevel@tonic-gate com_err(argv[0], retval, gettext("while initializing SAM")); 879*7c478bd9Sstevel@tonic-gate finish_realms(argv[0]); 880*7c478bd9Sstevel@tonic-gate return 1; 881*7c478bd9Sstevel@tonic-gate } 882*7c478bd9Sstevel@tonic-gate 883*7c478bd9Sstevel@tonic-gate if ((retval = setup_network(argv[0]))) { 884*7c478bd9Sstevel@tonic-gate com_err(argv[0], retval, gettext("while initializing network")); 885*7c478bd9Sstevel@tonic-gate finish_realms(argv[0]); 886*7c478bd9Sstevel@tonic-gate return 1; 887*7c478bd9Sstevel@tonic-gate } 888*7c478bd9Sstevel@tonic-gate if (!nofork && daemon(0, 0)) { 889*7c478bd9Sstevel@tonic-gate com_err(argv[0], errno, gettext("while detaching from tty")); 890*7c478bd9Sstevel@tonic-gate finish_realms(argv[0]); 891*7c478bd9Sstevel@tonic-gate return 1; 892*7c478bd9Sstevel@tonic-gate } 893*7c478bd9Sstevel@tonic-gate if (retval = krb5_klog_syslog(LOG_INFO, "commencing operation")) { 894*7c478bd9Sstevel@tonic-gate com_err(argv[0], retval, gettext("while logging message")); 895*7c478bd9Sstevel@tonic-gate errout++; 896*7c478bd9Sstevel@tonic-gate }; 897*7c478bd9Sstevel@tonic-gate 898*7c478bd9Sstevel@tonic-gate if ((retval = listen_and_process(argv[0]))) { 899*7c478bd9Sstevel@tonic-gate com_err(argv[0], retval, gettext("while processing network requests")); 900*7c478bd9Sstevel@tonic-gate errout++; 901*7c478bd9Sstevel@tonic-gate } 902*7c478bd9Sstevel@tonic-gate if ((retval = closedown_network(argv[0]))) { 903*7c478bd9Sstevel@tonic-gate com_err(argv[0], retval, gettext("while shutting down network")); 904*7c478bd9Sstevel@tonic-gate errout++; 905*7c478bd9Sstevel@tonic-gate } 906*7c478bd9Sstevel@tonic-gate krb5_klog_syslog(LOG_INFO, "shutting down"); 907*7c478bd9Sstevel@tonic-gate krb5_klog_close(kdc_context); 908*7c478bd9Sstevel@tonic-gate finish_realms(argv[0]); 909*7c478bd9Sstevel@tonic-gate krb5_free_context(kcontext); 910*7c478bd9Sstevel@tonic-gate return errout; 911*7c478bd9Sstevel@tonic-gate } 912