xref: /titanic_52/usr/src/cmd/krb5/krb5kdc/main.c (revision 7c64d3750da7fda7e450b8f9b0b963905ded6379)
17c478bd9Sstevel@tonic-gate /*
2*7c64d375Smp153739  * Copyright 2008 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 
5656a424ccSmp153739 #ifdef KRB5_KRB4_COMPAT
5756a424ccSmp153739 #include <des.h>
5856a424ccSmp153739 #endif
5956a424ccSmp153739 
6056a424ccSmp153739 #if defined(NEED_DAEMON_PROTO)
6156a424ccSmp153739 extern int daemon(int, int);
6256a424ccSmp153739 #endif
637c478bd9Sstevel@tonic-gate 
64505d05c7Sgtb void usage (char *);
657c478bd9Sstevel@tonic-gate 
66505d05c7Sgtb krb5_sigtype request_exit (int);
67505d05c7Sgtb krb5_sigtype request_hup  (int);
687c478bd9Sstevel@tonic-gate 
69505d05c7Sgtb void setup_signal_handlers (void);
707c478bd9Sstevel@tonic-gate 
71505d05c7Sgtb krb5_error_code setup_sam (void);
727c478bd9Sstevel@tonic-gate 
73505d05c7Sgtb void initialize_realms (krb5_context, int, char **);
747c478bd9Sstevel@tonic-gate 
75505d05c7Sgtb void finish_realms (char *);
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate static int nofork = 0;
787c478bd9Sstevel@tonic-gate static int rkey_init_done = 0;
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate /* Solaris Kerberos: global here that other functions access */
817c478bd9Sstevel@tonic-gate int max_tcp_data_connections;
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGNALS
847c478bd9Sstevel@tonic-gate static struct sigaction s_action;
857c478bd9Sstevel@tonic-gate #endif /* POSIX_SIGNALS */
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate #define	KRB5_KDC_MAX_REALMS	32
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate /*
907c478bd9Sstevel@tonic-gate  * Find the realm entry for a given realm.
917c478bd9Sstevel@tonic-gate  */
927c478bd9Sstevel@tonic-gate kdc_realm_t *
9356a424ccSmp153739 find_realm_data(char *rname, krb5_ui_4 rsize)
947c478bd9Sstevel@tonic-gate {
957c478bd9Sstevel@tonic-gate     int i;
967c478bd9Sstevel@tonic-gate     for (i=0; i<kdc_numrealms; i++) {
977c478bd9Sstevel@tonic-gate 	if ((rsize == strlen(kdc_realmlist[i]->realm_name)) &&
987c478bd9Sstevel@tonic-gate 	    !strncmp(rname, kdc_realmlist[i]->realm_name, rsize))
997c478bd9Sstevel@tonic-gate 	    return(kdc_realmlist[i]);
1007c478bd9Sstevel@tonic-gate     }
1017c478bd9Sstevel@tonic-gate     return((kdc_realm_t *) NULL);
1027c478bd9Sstevel@tonic-gate }
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate krb5_error_code
10556a424ccSmp153739 setup_server_realm(krb5_principal sprinc)
1067c478bd9Sstevel@tonic-gate {
1077c478bd9Sstevel@tonic-gate     krb5_error_code	kret;
1087c478bd9Sstevel@tonic-gate     kdc_realm_t		*newrealm;
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate     kret = 0;
1117c478bd9Sstevel@tonic-gate     if (kdc_numrealms > 1) {
1127c478bd9Sstevel@tonic-gate 	if (!(newrealm = find_realm_data(sprinc->realm.data,
1137c478bd9Sstevel@tonic-gate 					 (krb5_ui_4) sprinc->realm.length)))
1147c478bd9Sstevel@tonic-gate 	    kret = ENOENT;
1157c478bd9Sstevel@tonic-gate 	else
1167c478bd9Sstevel@tonic-gate 	    kdc_active_realm = newrealm;
1177c478bd9Sstevel@tonic-gate     }
1187c478bd9Sstevel@tonic-gate     else
1197c478bd9Sstevel@tonic-gate 	kdc_active_realm = kdc_realmlist[0];
1207c478bd9Sstevel@tonic-gate     return(kret);
1217c478bd9Sstevel@tonic-gate }
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate static void
12456a424ccSmp153739 finish_realm(kdc_realm_t *rdp)
1257c478bd9Sstevel@tonic-gate {
1267c478bd9Sstevel@tonic-gate     if (rdp->realm_dbname)
1277c478bd9Sstevel@tonic-gate 	free(rdp->realm_dbname);
1287c478bd9Sstevel@tonic-gate     if (rdp->realm_mpname)
1297c478bd9Sstevel@tonic-gate 	free(rdp->realm_mpname);
1307c478bd9Sstevel@tonic-gate     if (rdp->realm_stash)
1317c478bd9Sstevel@tonic-gate 	free(rdp->realm_stash);
1327c478bd9Sstevel@tonic-gate     if (rdp->realm_ports)
1337c478bd9Sstevel@tonic-gate 	free(rdp->realm_ports);
1347c478bd9Sstevel@tonic-gate     if (rdp->realm_tcp_ports)
1357c478bd9Sstevel@tonic-gate 	free(rdp->realm_tcp_ports);
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 	krb5_db_fini(rdp->realm_context);
1467c478bd9Sstevel@tonic-gate 	if (rdp->realm_tgsprinc)
1477c478bd9Sstevel@tonic-gate 	    krb5_free_principal(rdp->realm_context, rdp->realm_tgsprinc);
1487c478bd9Sstevel@tonic-gate 	krb5_free_context(rdp->realm_context);
1497c478bd9Sstevel@tonic-gate     }
15056a424ccSmp153739     memset((char *) rdp, 0, sizeof(*rdp));
1517c478bd9Sstevel@tonic-gate     free(rdp);
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate /*
1557c478bd9Sstevel@tonic-gate  * Initialize a realm control structure from the alternate profile or from
1567c478bd9Sstevel@tonic-gate  * the specified defaults.
1577c478bd9Sstevel@tonic-gate  *
1587c478bd9Sstevel@tonic-gate  * After we're complete here, the essence of the realm is embodied in the
1597c478bd9Sstevel@tonic-gate  * realm data and we should be all set to begin operation for that realm.
1607c478bd9Sstevel@tonic-gate  */
1617c478bd9Sstevel@tonic-gate static krb5_error_code
162*7c64d375Smp153739 init_realm(krb5_context kcontext, char *progname, kdc_realm_t *rdp, char *realm,
16356a424ccSmp153739 	   char *def_mpname, krb5_enctype def_enctype, char *def_udp_ports,
16454925bf6Swillf 	   char *def_tcp_ports, krb5_boolean def_manual, char **db_args)
1657c478bd9Sstevel@tonic-gate {
1667c478bd9Sstevel@tonic-gate     krb5_error_code	kret;
1677c478bd9Sstevel@tonic-gate     krb5_boolean	manual;
1687c478bd9Sstevel@tonic-gate     krb5_realm_params	*rparams;
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate     memset((char *) rdp, 0, sizeof(kdc_realm_t));
1717c478bd9Sstevel@tonic-gate     if (!realm) {
1727c478bd9Sstevel@tonic-gate 	kret = EINVAL;
1737c478bd9Sstevel@tonic-gate 	goto whoops;
1747c478bd9Sstevel@tonic-gate     }
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate     rdp->realm_name = realm;
17754925bf6Swillf     kret = krb5int_init_context_kdc(&rdp->realm_context);
1787c478bd9Sstevel@tonic-gate     if (kret) {
1797c478bd9Sstevel@tonic-gate 	com_err(progname, kret, gettext("while getting context for realm %s"),
1807c478bd9Sstevel@tonic-gate 		realm);
1817c478bd9Sstevel@tonic-gate 	goto whoops;
1827c478bd9Sstevel@tonic-gate     }
1837c478bd9Sstevel@tonic-gate 
184*7c64d375Smp153739     /*
185*7c64d375Smp153739      * Solaris Kerberos:
186*7c64d375Smp153739      * Set the current context to that of the realm being init'ed
187*7c64d375Smp153739      */
188*7c64d375Smp153739     krb5_klog_set_context(rdp->realm_context);
189*7c64d375Smp153739 
1907c478bd9Sstevel@tonic-gate     kret = krb5_read_realm_params(rdp->realm_context, rdp->realm_name,
1917c478bd9Sstevel@tonic-gate 				  (char *) NULL, (char *) NULL, &rparams);
1927c478bd9Sstevel@tonic-gate     if (kret) {
1937c478bd9Sstevel@tonic-gate 	com_err(progname, kret, gettext("while reading realm parameters"));
1947c478bd9Sstevel@tonic-gate 	goto whoops;
1957c478bd9Sstevel@tonic-gate     }
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate     /* Handle profile file name */
1987c478bd9Sstevel@tonic-gate     if (rparams && rparams->realm_profile)
1997c478bd9Sstevel@tonic-gate 	rdp->realm_profile = strdup(rparams->realm_profile);
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate     /* Handle master key name */
2027c478bd9Sstevel@tonic-gate     if (rparams && rparams->realm_mkey_name)
2037c478bd9Sstevel@tonic-gate 	rdp->realm_mpname = strdup(rparams->realm_mkey_name);
2047c478bd9Sstevel@tonic-gate     else
2057c478bd9Sstevel@tonic-gate 	rdp->realm_mpname = (def_mpname) ? strdup(def_mpname) :
2067c478bd9Sstevel@tonic-gate 	    strdup(KRB5_KDB_M_NAME);
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate     /* Handle KDC ports */
2097c478bd9Sstevel@tonic-gate     if (rparams && rparams->realm_kdc_ports)
2107c478bd9Sstevel@tonic-gate 	rdp->realm_ports = strdup(rparams->realm_kdc_ports);
2117c478bd9Sstevel@tonic-gate     else
2127c478bd9Sstevel@tonic-gate 	rdp->realm_ports = strdup(def_udp_ports);
2137c478bd9Sstevel@tonic-gate     if (rparams && rparams->realm_kdc_tcp_ports)
2147c478bd9Sstevel@tonic-gate 	rdp->realm_tcp_ports = strdup(rparams->realm_kdc_tcp_ports);
2157c478bd9Sstevel@tonic-gate     else
2167c478bd9Sstevel@tonic-gate 	rdp->realm_tcp_ports = strdup(def_tcp_ports);
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate     /* Handle stash file */
2197c478bd9Sstevel@tonic-gate     if (rparams && rparams->realm_stash_file) {
2207c478bd9Sstevel@tonic-gate 	rdp->realm_stash = strdup(rparams->realm_stash_file);
2217c478bd9Sstevel@tonic-gate 	manual = FALSE;
2227c478bd9Sstevel@tonic-gate     } else
2237c478bd9Sstevel@tonic-gate 	manual = def_manual;
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate     /* Handle master key type */
2267c478bd9Sstevel@tonic-gate     if (rparams && rparams->realm_enctype_valid)
2277c478bd9Sstevel@tonic-gate 	rdp->realm_mkey.enctype = (krb5_enctype) rparams->realm_enctype;
2287c478bd9Sstevel@tonic-gate     else
2297c478bd9Sstevel@tonic-gate 	rdp->realm_mkey.enctype = manual ? def_enctype : ENCTYPE_UNKNOWN;
23056a424ccSmp153739 
23156a424ccSmp153739     /* Handle reject-bad-transit flag */
23256a424ccSmp153739     if (rparams && rparams->realm_reject_bad_transit_valid)
23356a424ccSmp153739 	rdp->realm_reject_bad_transit = rparams->realm_reject_bad_transit;
23456a424ccSmp153739     else
23556a424ccSmp153739 	rdp->realm_reject_bad_transit = 1;
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate     /* Handle ticket maximum life */
23856a424ccSmp153739     rdp->realm_maxlife = (rparams && rparams->realm_max_life_valid) ?
23956a424ccSmp153739 	rparams->realm_max_life : KRB5_KDB_MAX_LIFE;
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate     /* Handle ticket renewable maximum life */
24256a424ccSmp153739     rdp->realm_maxrlife = (rparams && rparams->realm_max_rlife_valid) ?
24356a424ccSmp153739 	rparams->realm_max_rlife : KRB5_KDB_MAX_RLIFE;
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate     if (rparams)
2467c478bd9Sstevel@tonic-gate 	krb5_free_realm_params(rdp->realm_context, rparams);
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate     /*
2497c478bd9Sstevel@tonic-gate      * We've got our parameters, now go and setup our realm context.
2507c478bd9Sstevel@tonic-gate      */
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate     /* Set the default realm of this context */
2537c478bd9Sstevel@tonic-gate     if ((kret = krb5_set_default_realm(rdp->realm_context, realm))) {
2547c478bd9Sstevel@tonic-gate 	com_err(progname, kret, gettext("while setting default realm to %s"),
2557c478bd9Sstevel@tonic-gate 		realm);
2567c478bd9Sstevel@tonic-gate 	goto whoops;
2577c478bd9Sstevel@tonic-gate     }
2587c478bd9Sstevel@tonic-gate 
25954925bf6Swillf     /* first open the database  before doing anything */
26054925bf6Swillf #ifdef KRBCONF_KDC_MODIFIES_KDB
26154925bf6Swillf     if ((kret = krb5_db_open(rdp->realm_context, db_args,
26254925bf6Swillf 			     KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_KDC))) {
26354925bf6Swillf #else
26454925bf6Swillf     if ((kret = krb5_db_open(rdp->realm_context, db_args,
26554925bf6Swillf 			     KRB5_KDB_OPEN_RO | KRB5_KDB_SRV_TYPE_KDC))) {
26654925bf6Swillf #endif
267*7c64d375Smp153739 	/*
268*7c64d375Smp153739 	 * Solaris Kerberos:
269*7c64d375Smp153739 	 * Make sure that error messages are printed using gettext
270*7c64d375Smp153739 	 */
27154925bf6Swillf 	com_err(progname, kret,
272*7c64d375Smp153739 	    gettext("while initializing database for realm %s"), realm);
27354925bf6Swillf 	goto whoops;
27454925bf6Swillf     }
27554925bf6Swillf 
2767c478bd9Sstevel@tonic-gate     /* Assemble and parse the master key name */
2777c478bd9Sstevel@tonic-gate     if ((kret = krb5_db_setup_mkey_name(rdp->realm_context, rdp->realm_mpname,
2787c478bd9Sstevel@tonic-gate 					rdp->realm_name, (char **) NULL,
2797c478bd9Sstevel@tonic-gate 					&rdp->realm_mprinc))) {
2807c478bd9Sstevel@tonic-gate 	com_err(progname, kret,
2817c478bd9Sstevel@tonic-gate 		gettext("while setting up master key name %s for realm %s"),
2827c478bd9Sstevel@tonic-gate 		rdp->realm_mpname, realm);
2837c478bd9Sstevel@tonic-gate 	goto whoops;
2847c478bd9Sstevel@tonic-gate     }
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate     /*
2877c478bd9Sstevel@tonic-gate      * Get the master key.
2887c478bd9Sstevel@tonic-gate      */
2897c478bd9Sstevel@tonic-gate     if ((kret = krb5_db_fetch_mkey(rdp->realm_context, rdp->realm_mprinc,
2907c478bd9Sstevel@tonic-gate 				   rdp->realm_mkey.enctype, manual,
2917c478bd9Sstevel@tonic-gate 				   FALSE, rdp->realm_stash,
2927c478bd9Sstevel@tonic-gate 				   0, &rdp->realm_mkey))) {
2937c478bd9Sstevel@tonic-gate 	com_err(progname, kret,
2947c478bd9Sstevel@tonic-gate 		gettext("while fetching master key %s for realm %s"),
2957c478bd9Sstevel@tonic-gate 		rdp->realm_mpname, realm);
2967c478bd9Sstevel@tonic-gate 	goto whoops;
2977c478bd9Sstevel@tonic-gate     }
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate     /* Verify the master key */
3007c478bd9Sstevel@tonic-gate     if ((kret = krb5_db_verify_master_key(rdp->realm_context,
3017c478bd9Sstevel@tonic-gate 					  rdp->realm_mprinc,
3027c478bd9Sstevel@tonic-gate 					  &rdp->realm_mkey))) {
3037c478bd9Sstevel@tonic-gate 	com_err(progname, kret,
3047c478bd9Sstevel@tonic-gate 		gettext("while verifying master key for realm %s"),
3057c478bd9Sstevel@tonic-gate 		realm);
3067c478bd9Sstevel@tonic-gate 	goto whoops;
3077c478bd9Sstevel@tonic-gate     }
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate     if ((kret = krb5_db_set_mkey(rdp->realm_context, &rdp->realm_mkey))) {
3107c478bd9Sstevel@tonic-gate 	com_err(progname, kret,
3117c478bd9Sstevel@tonic-gate 		gettext("while processing master key for realm %s"),
3127c478bd9Sstevel@tonic-gate 		realm);
3137c478bd9Sstevel@tonic-gate 	goto whoops;
3147c478bd9Sstevel@tonic-gate     }
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate     /* Set up the keytab */
31756a424ccSmp153739     if ((kret = krb5_ktkdb_resolve(rdp->realm_context, NULL,
3187c478bd9Sstevel@tonic-gate 				   &rdp->realm_keytab))) {
3197c478bd9Sstevel@tonic-gate 	com_err(progname, kret,
3207c478bd9Sstevel@tonic-gate 		gettext("while resolving kdb keytab for realm %s"),
3217c478bd9Sstevel@tonic-gate 		realm);
3227c478bd9Sstevel@tonic-gate 	goto whoops;
3237c478bd9Sstevel@tonic-gate     }
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate     /* Preformat the TGS name */
3267c478bd9Sstevel@tonic-gate     if ((kret = krb5_build_principal(rdp->realm_context, &rdp->realm_tgsprinc,
3277c478bd9Sstevel@tonic-gate 				     strlen(realm), realm, KRB5_TGS_NAME,
3287c478bd9Sstevel@tonic-gate 				     realm, (char *) NULL))) {
3297c478bd9Sstevel@tonic-gate 	com_err(progname, kret,
3307c478bd9Sstevel@tonic-gate 		gettext("while building TGS name for realm %s"),
3317c478bd9Sstevel@tonic-gate 		realm);
3327c478bd9Sstevel@tonic-gate 	goto whoops;
3337c478bd9Sstevel@tonic-gate     }
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate     if (!rkey_init_done) {
3367c478bd9Sstevel@tonic-gate 	krb5_data seed;
3377c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
3387c478bd9Sstevel@tonic-gate 	krb5_keyblock temp_key;
3397c478bd9Sstevel@tonic-gate #endif
3407c478bd9Sstevel@tonic-gate 	/*
3417c478bd9Sstevel@tonic-gate 	 * If all that worked, then initialize the random key
3427c478bd9Sstevel@tonic-gate 	 * generators.
3437c478bd9Sstevel@tonic-gate 	 */
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate 	seed.length = rdp->realm_mkey.length;
3467c478bd9Sstevel@tonic-gate 	seed.data = (char *)rdp->realm_mkey.contents;
34756a424ccSmp153739 /* SUNW14resync - XXX */
34856a424ccSmp153739 #if 0
34956a424ccSmp153739 	if ((kret = krb5_c_random_add_entropy(rdp->realm_context,
35056a424ccSmp153739 					     KRB5_C_RANDSOURCE_TRUSTEDPARTY, &seed)))
3517c478bd9Sstevel@tonic-gate 	    goto whoops;
35256a424ccSmp153739 #endif
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
3557c478bd9Sstevel@tonic-gate 	if ((kret = krb5_c_make_random_key(rdp->realm_context,
3567c478bd9Sstevel@tonic-gate 					   ENCTYPE_DES_CBC_CRC, &temp_key))) {
3577c478bd9Sstevel@tonic-gate 	    com_err(progname, kret,
3587c478bd9Sstevel@tonic-gate 		    "while initializing V4 random key generator");
3597c478bd9Sstevel@tonic-gate 	    goto whoops;
3607c478bd9Sstevel@tonic-gate 	}
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate 	(void) des_init_random_number_generator(temp_key.contents);
3637c478bd9Sstevel@tonic-gate 	krb5_free_keyblock_contents(rdp->realm_context, &temp_key);
3647c478bd9Sstevel@tonic-gate #endif
3657c478bd9Sstevel@tonic-gate 	rkey_init_done = 1;
3667c478bd9Sstevel@tonic-gate     }
3677c478bd9Sstevel@tonic-gate  whoops:
3687c478bd9Sstevel@tonic-gate     /*
3697c478bd9Sstevel@tonic-gate      * If we choked, then clean up any dirt we may have dropped on the floor.
3707c478bd9Sstevel@tonic-gate      */
3717c478bd9Sstevel@tonic-gate     if (kret) {
37256a424ccSmp153739 
3737c478bd9Sstevel@tonic-gate 	finish_realm(rdp);
3747c478bd9Sstevel@tonic-gate     }
375*7c64d375Smp153739 
376*7c64d375Smp153739     /*
377*7c64d375Smp153739      * Solaris Kerberos:
378*7c64d375Smp153739      * Set the current context back to the general context
379*7c64d375Smp153739      */
380*7c64d375Smp153739     krb5_klog_set_context(kcontext);
381*7c64d375Smp153739 
3827c478bd9Sstevel@tonic-gate     return(kret);
3837c478bd9Sstevel@tonic-gate }
3847c478bd9Sstevel@tonic-gate 
3857c478bd9Sstevel@tonic-gate krb5_sigtype
38656a424ccSmp153739 request_exit(int signo)
3877c478bd9Sstevel@tonic-gate {
3887c478bd9Sstevel@tonic-gate     signal_requests_exit = 1;
3897c478bd9Sstevel@tonic-gate 
3907c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGTYPE
3917c478bd9Sstevel@tonic-gate     return;
3927c478bd9Sstevel@tonic-gate #else
3937c478bd9Sstevel@tonic-gate     return(0);
3947c478bd9Sstevel@tonic-gate #endif
3957c478bd9Sstevel@tonic-gate }
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate krb5_sigtype
39856a424ccSmp153739 request_hup(int signo)
3997c478bd9Sstevel@tonic-gate {
4007c478bd9Sstevel@tonic-gate     signal_requests_hup = 1;
4017c478bd9Sstevel@tonic-gate 
4027c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGTYPE
4037c478bd9Sstevel@tonic-gate     return;
4047c478bd9Sstevel@tonic-gate #else
4057c478bd9Sstevel@tonic-gate     return(0);
4067c478bd9Sstevel@tonic-gate #endif
4077c478bd9Sstevel@tonic-gate }
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate void
41056a424ccSmp153739 setup_signal_handlers(void)
4117c478bd9Sstevel@tonic-gate {
4127c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGNALS
4137c478bd9Sstevel@tonic-gate     (void) sigemptyset(&s_action.sa_mask);
4147c478bd9Sstevel@tonic-gate     s_action.sa_flags = 0;
4157c478bd9Sstevel@tonic-gate     s_action.sa_handler = request_exit;
4167c478bd9Sstevel@tonic-gate     (void) sigaction(SIGINT, &s_action, (struct sigaction *) NULL);
4177c478bd9Sstevel@tonic-gate     (void) sigaction(SIGTERM, &s_action, (struct sigaction *) NULL);
4187c478bd9Sstevel@tonic-gate     s_action.sa_handler = request_hup;
4197c478bd9Sstevel@tonic-gate     (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL);
42054925bf6Swillf     s_action.sa_handler = SIG_IGN;
42154925bf6Swillf     (void) sigaction(SIGPIPE, &s_action, (struct sigaction *) NULL);
4227c478bd9Sstevel@tonic-gate #else  /* POSIX_SIGNALS */
4237c478bd9Sstevel@tonic-gate     signal(SIGINT, request_exit);
4247c478bd9Sstevel@tonic-gate     signal(SIGTERM, request_exit);
4257c478bd9Sstevel@tonic-gate     signal(SIGHUP, request_hup);
42654925bf6Swillf     signal(SIGPIPE, SIG_IGN);
4277c478bd9Sstevel@tonic-gate #endif /* POSIX_SIGNALS */
4287c478bd9Sstevel@tonic-gate 
4297c478bd9Sstevel@tonic-gate     return;
4307c478bd9Sstevel@tonic-gate }
4317c478bd9Sstevel@tonic-gate 
4327c478bd9Sstevel@tonic-gate krb5_error_code
43356a424ccSmp153739 setup_sam(void)
4347c478bd9Sstevel@tonic-gate {
4357c478bd9Sstevel@tonic-gate     return krb5_c_make_random_key(kdc_context, ENCTYPE_DES_CBC_MD5, &psr_key);
4367c478bd9Sstevel@tonic-gate }
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate void
43956a424ccSmp153739 usage(char *name)
4407c478bd9Sstevel@tonic-gate {
4417c478bd9Sstevel@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);
44254925bf6Swillf     fprintf(stderr, "usage: %s [-x db_args]* [-d dbpathname] [-r dbrealmname] [-R replaycachename ]\n\t[-m] [-k masterenctype] [-M masterkeyname] [-p port] [-X] [-n]\n"
44354925bf6Swillf 	    "\nwhere,\n\t[-x db_args]* - any number of database specific arguments.\n"
44454925bf6Swillf 	    "\t\t\tLook at each database documentation for supported arguments\n",
44554925bf6Swillf 	    name);
4467c478bd9Sstevel@tonic-gate     return;
4477c478bd9Sstevel@tonic-gate }
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate void
45056a424ccSmp153739 initialize_realms(krb5_context kcontext, int argc, char **argv)
4517c478bd9Sstevel@tonic-gate {
4527c478bd9Sstevel@tonic-gate     int 		c;
4537c478bd9Sstevel@tonic-gate     char		*db_name = (char *) NULL;
4547c478bd9Sstevel@tonic-gate     char		*mkey_name = (char *) NULL;
4557c478bd9Sstevel@tonic-gate     char		*rcname = KDCRCACHE;
456*7c64d375Smp153739     char		*lrealm = NULL;
4577c478bd9Sstevel@tonic-gate     krb5_error_code	retval;
4587c478bd9Sstevel@tonic-gate     krb5_enctype	menctype = ENCTYPE_UNKNOWN;
4597c478bd9Sstevel@tonic-gate     kdc_realm_t		*rdatap;
4607c478bd9Sstevel@tonic-gate     krb5_boolean	manual = FALSE;
4617c478bd9Sstevel@tonic-gate     char		*default_udp_ports = 0;
4627c478bd9Sstevel@tonic-gate     char		*default_tcp_ports = 0;
4637c478bd9Sstevel@tonic-gate     krb5_pointer	aprof;
4647c478bd9Sstevel@tonic-gate     const char		*hierarchy[3];
46554925bf6Swillf     char               **db_args      = NULL;
46654925bf6Swillf     int                  db_args_size = 0;
46754925bf6Swillf 
4687c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
4697c478bd9Sstevel@tonic-gate     char                *v4mode = 0;
4707c478bd9Sstevel@tonic-gate #endif
4717c478bd9Sstevel@tonic-gate     extern char *optarg;
4727c478bd9Sstevel@tonic-gate 
4737c478bd9Sstevel@tonic-gate     if (!krb5_aprof_init(DEFAULT_KDC_PROFILE, KDC_PROFILE_ENV, &aprof)) {
4747c478bd9Sstevel@tonic-gate 	hierarchy[0] = "kdcdefaults";
4757c478bd9Sstevel@tonic-gate 	hierarchy[1] = "kdc_ports";
4767c478bd9Sstevel@tonic-gate 	hierarchy[2] = (char *) NULL;
4777c478bd9Sstevel@tonic-gate 	if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_udp_ports))
4787c478bd9Sstevel@tonic-gate 	    default_udp_ports = 0;
4797c478bd9Sstevel@tonic-gate 	hierarchy[1] = "kdc_tcp_ports";
4807c478bd9Sstevel@tonic-gate 	if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_tcp_ports))
4817c478bd9Sstevel@tonic-gate 	    default_tcp_ports = 0;
4827c478bd9Sstevel@tonic-gate 	hierarchy[1] = "kdc_max_tcp_connections";
4837c478bd9Sstevel@tonic-gate 	if (krb5_aprof_get_int32(aprof, hierarchy, TRUE,
4847c478bd9Sstevel@tonic-gate 		&max_tcp_data_connections)) {
4857c478bd9Sstevel@tonic-gate 	    max_tcp_data_connections = DEFAULT_KDC_TCP_CONNECTIONS;
4867c478bd9Sstevel@tonic-gate 	} else if (max_tcp_data_connections < MIN_KDC_TCP_CONNECTIONS) {
4877c478bd9Sstevel@tonic-gate 	    max_tcp_data_connections = DEFAULT_KDC_TCP_CONNECTIONS;
4887c478bd9Sstevel@tonic-gate 	}
4897c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
4907c478bd9Sstevel@tonic-gate 	hierarchy[1] = "v4_mode";
4917c478bd9Sstevel@tonic-gate 	if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &v4mode))
4927c478bd9Sstevel@tonic-gate 	    v4mode = 0;
4937c478bd9Sstevel@tonic-gate #endif
4947c478bd9Sstevel@tonic-gate 	/* aprof_init can return 0 with aprof == NULL */
4957c478bd9Sstevel@tonic-gate 	if (aprof)
4967c478bd9Sstevel@tonic-gate 	     krb5_aprof_finish(aprof);
4977c478bd9Sstevel@tonic-gate     }
4987c478bd9Sstevel@tonic-gate     if (default_udp_ports == 0)
4997c478bd9Sstevel@tonic-gate 	default_udp_ports = strdup(DEFAULT_KDC_UDP_PORTLIST);
5007c478bd9Sstevel@tonic-gate     if (default_tcp_ports == 0)
5017c478bd9Sstevel@tonic-gate 	default_tcp_ports = strdup(DEFAULT_KDC_TCP_PORTLIST);
5027c478bd9Sstevel@tonic-gate     /*
5037c478bd9Sstevel@tonic-gate      * Loop through the option list.  Each time we encounter a realm name,
5047c478bd9Sstevel@tonic-gate      * use the previously scanned options to fill in for defaults.
5057c478bd9Sstevel@tonic-gate      */
50654925bf6Swillf     while ((c = getopt(argc, argv, "x:r:d:mM:k:R:e:p:s:n4:X3")) != -1) {
5077c478bd9Sstevel@tonic-gate 	switch(c) {
50854925bf6Swillf 	case 'x':
50954925bf6Swillf 	    db_args_size++;
51054925bf6Swillf 	    {
51154925bf6Swillf 		char **temp = realloc( db_args, sizeof(char*) * (db_args_size+1)); /* one for NULL */
51254925bf6Swillf 		if( temp == NULL )
51354925bf6Swillf 		{
514*7c64d375Smp153739 			/* Solaris Kerberos: Keep error messages consistent */
515*7c64d375Smp153739 		    com_err(argv[0], errno, gettext("while initializing KDC"));
51654925bf6Swillf 		    exit(1);
51754925bf6Swillf 		}
51854925bf6Swillf 
51954925bf6Swillf 		db_args = temp;
52054925bf6Swillf 	    }
52154925bf6Swillf 	    db_args[db_args_size-1] = optarg;
52254925bf6Swillf 	    db_args[db_args_size]   = NULL;
52354925bf6Swillf 	  break;
52454925bf6Swillf 
5257c478bd9Sstevel@tonic-gate 	case 'r':			/* realm name for db */
5267c478bd9Sstevel@tonic-gate 	    if (!find_realm_data(optarg, (krb5_ui_4) strlen(optarg))) {
5277c478bd9Sstevel@tonic-gate 		if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) {
528*7c64d375Smp153739 		    if ((retval = init_realm(kcontext, argv[0], rdatap, optarg,
5297c478bd9Sstevel@tonic-gate 					     mkey_name, menctype,
5307c478bd9Sstevel@tonic-gate 					     default_udp_ports,
53154925bf6Swillf 					     default_tcp_ports, manual, db_args))) {
532*7c64d375Smp153739 			/* Solaris Kerberos: Keep error messages consistent */
533*7c64d375Smp153739 			com_err(argv[0], retval, gettext("while initializing realm %s"), optarg);
5347c478bd9Sstevel@tonic-gate 			exit(1);
5357c478bd9Sstevel@tonic-gate 		    }
5367c478bd9Sstevel@tonic-gate 		    kdc_realmlist[kdc_numrealms] = rdatap;
5377c478bd9Sstevel@tonic-gate 		    kdc_numrealms++;
53854925bf6Swillf 		    free(db_args), db_args=NULL, db_args_size = 0;
53954925bf6Swillf 		}
54054925bf6Swillf 		else
54154925bf6Swillf 		{
542*7c64d375Smp153739 			/* Solaris Kerberos: Keep error messages consistent */
543*7c64d375Smp153739 			com_err(argv[0], errno, gettext("while initializing realm %s"), optarg);
54454925bf6Swillf 			exit(1);
5457c478bd9Sstevel@tonic-gate 		}
5467c478bd9Sstevel@tonic-gate 	    }
5477c478bd9Sstevel@tonic-gate 	    break;
5487c478bd9Sstevel@tonic-gate 	case 'd':			/* pathname for db */
54954925bf6Swillf 	    /* now db_name is not a seperate argument. It has to be passed as part of the db_args */
55054925bf6Swillf 	    if( db_name == NULL )
55154925bf6Swillf 	    {
55254925bf6Swillf 		db_name = malloc(sizeof("dbname=") + strlen(optarg));
55354925bf6Swillf 		if( db_name == NULL )
55454925bf6Swillf 		{
555*7c64d375Smp153739 			/* Solaris Kerberos: Keep error messages consistent */
556*7c64d375Smp153739 			com_err(argv[0], errno, gettext("while initializing KDC"));
55754925bf6Swillf 			exit(1);
55854925bf6Swillf 		}
55954925bf6Swillf 
56054925bf6Swillf 		sprintf( db_name, "dbname=%s", optarg);
56154925bf6Swillf 	    }
56254925bf6Swillf 
56354925bf6Swillf 	    db_args_size++;
56454925bf6Swillf 	    {
56554925bf6Swillf 		char **temp = realloc( db_args, sizeof(char*) * (db_args_size+1)); /* one for NULL */
56654925bf6Swillf 		if( temp == NULL )
56754925bf6Swillf 		{
568*7c64d375Smp153739 			/* Solaris Kerberos: Keep error messages consistent */
569*7c64d375Smp153739 		    com_err(argv[0], errno, gettext("while initializing KDC"));
57054925bf6Swillf 		    exit(1);
57154925bf6Swillf 		}
57254925bf6Swillf 
57354925bf6Swillf 		db_args = temp;
57454925bf6Swillf 	    }
57554925bf6Swillf 	    db_args[db_args_size-1] = db_name;
57654925bf6Swillf 	    db_args[db_args_size]   = NULL;
5777c478bd9Sstevel@tonic-gate 	    break;
5787c478bd9Sstevel@tonic-gate 	case 'm':			/* manual type-in of master key */
5797c478bd9Sstevel@tonic-gate 	    manual = TRUE;
5807c478bd9Sstevel@tonic-gate 	    if (menctype == ENCTYPE_UNKNOWN)
5817c478bd9Sstevel@tonic-gate 		menctype = ENCTYPE_DES_CBC_CRC;
5827c478bd9Sstevel@tonic-gate 	    break;
5837c478bd9Sstevel@tonic-gate 	case 'M':			/* master key name in DB */
5847c478bd9Sstevel@tonic-gate 	    mkey_name = optarg;
5857c478bd9Sstevel@tonic-gate 	    break;
5867c478bd9Sstevel@tonic-gate 	case 'n':
5877c478bd9Sstevel@tonic-gate 	    nofork++;			/* don't detach from terminal */
5887c478bd9Sstevel@tonic-gate 	    break;
5897c478bd9Sstevel@tonic-gate 	case 'k':			/* enctype for master key */
590*7c64d375Smp153739 		/* Solaris Kerberos: Keep error messages consistent */
591*7c64d375Smp153739 	    if (retval = krb5_string_to_enctype(optarg, &menctype))
592*7c64d375Smp153739 		com_err(argv[0], retval,
593*7c64d375Smp153739 		    gettext("while converting %s to an enctype"), optarg);
5947c478bd9Sstevel@tonic-gate 	    break;
5957c478bd9Sstevel@tonic-gate 	case 'R':
5967c478bd9Sstevel@tonic-gate 	    rcname = optarg;
5977c478bd9Sstevel@tonic-gate 	    break;
5987c478bd9Sstevel@tonic-gate 	case 'p':
5997c478bd9Sstevel@tonic-gate 	    if (default_udp_ports)
6007c478bd9Sstevel@tonic-gate 		free(default_udp_ports);
6017c478bd9Sstevel@tonic-gate 	    default_udp_ports = strdup(optarg);
6027c478bd9Sstevel@tonic-gate 
6037c478bd9Sstevel@tonic-gate 	    if (default_tcp_ports)
6047c478bd9Sstevel@tonic-gate 		free(default_tcp_ports);
6057c478bd9Sstevel@tonic-gate 	    default_tcp_ports = strdup(optarg);
6067c478bd9Sstevel@tonic-gate 
6077c478bd9Sstevel@tonic-gate 	    break;
6087c478bd9Sstevel@tonic-gate 	case '4':
6097c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
6107c478bd9Sstevel@tonic-gate 	    if (v4mode)
6117c478bd9Sstevel@tonic-gate 		free(v4mode);
6127c478bd9Sstevel@tonic-gate 	    v4mode = strdup(optarg);
6137c478bd9Sstevel@tonic-gate #endif
6147c478bd9Sstevel@tonic-gate 	    break;
61556a424ccSmp153739 	case 'X':
61656a424ccSmp153739 #ifdef KRB5_KRB4_COMPAT
61756a424ccSmp153739 		enable_v4_crossrealm(argv[0]);
6187c478bd9Sstevel@tonic-gate #endif
61956a424ccSmp153739 		break;
6207c478bd9Sstevel@tonic-gate 	case '?':
6217c478bd9Sstevel@tonic-gate 	default:
6227c478bd9Sstevel@tonic-gate 	    usage(argv[0]);
6237c478bd9Sstevel@tonic-gate 	    exit(1);
6247c478bd9Sstevel@tonic-gate 	}
6257c478bd9Sstevel@tonic-gate     }
6267c478bd9Sstevel@tonic-gate 
6277c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
6287c478bd9Sstevel@tonic-gate     /*
6297c478bd9Sstevel@tonic-gate      * Setup the v4 mode
6307c478bd9Sstevel@tonic-gate      */
6317c478bd9Sstevel@tonic-gate     process_v4_mode(argv[0], v4mode);
63254925bf6Swillf     free(v4mode);
6337c478bd9Sstevel@tonic-gate #endif
6347c478bd9Sstevel@tonic-gate 
6357c478bd9Sstevel@tonic-gate     /*
6367c478bd9Sstevel@tonic-gate      * Check to see if we processed any realms.
6377c478bd9Sstevel@tonic-gate      */
6387c478bd9Sstevel@tonic-gate     if (kdc_numrealms == 0) {
6397c478bd9Sstevel@tonic-gate 	/* no realm specified, use default realm */
6407c478bd9Sstevel@tonic-gate 	if ((retval = krb5_get_default_realm(kcontext, &lrealm))) {
6417c478bd9Sstevel@tonic-gate 	    com_err(argv[0], retval,
6427c478bd9Sstevel@tonic-gate 		gettext("while attempting to retrieve default realm"));
643*7c64d375Smp153739 	/* Solaris Kerberos: avoid double logging */
644*7c64d375Smp153739 #if 0
64556a424ccSmp153739 	    fprintf (stderr, "%s: %s, %s", argv[0], error_message (retval),
64656a424ccSmp153739 		gettext("attempting to retrieve default realm\n"));
647*7c64d375Smp153739 #endif
6487c478bd9Sstevel@tonic-gate 	    exit(1);
6497c478bd9Sstevel@tonic-gate 	}
6507c478bd9Sstevel@tonic-gate 	if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) {
651*7c64d375Smp153739 	    if ((retval = init_realm(kcontext, argv[0], rdatap, lrealm,
6527c478bd9Sstevel@tonic-gate 				     mkey_name, menctype, default_udp_ports,
65354925bf6Swillf 				     default_tcp_ports, manual, db_args))) {
654*7c64d375Smp153739 		/* Solaris Kerberos: Keep error messages consistent */
655*7c64d375Smp153739 		com_err(argv[0], retval, gettext("while initializing realm %s"), lrealm);
6567c478bd9Sstevel@tonic-gate 		exit(1);
6577c478bd9Sstevel@tonic-gate 	    }
6587c478bd9Sstevel@tonic-gate 	    kdc_realmlist[0] = rdatap;
6597c478bd9Sstevel@tonic-gate 	    kdc_numrealms++;
6607c478bd9Sstevel@tonic-gate 	}
6617c478bd9Sstevel@tonic-gate     }
6627c478bd9Sstevel@tonic-gate 
6637c478bd9Sstevel@tonic-gate #ifdef USE_RCACHE
6647c478bd9Sstevel@tonic-gate     /*
6657c478bd9Sstevel@tonic-gate      * Now handle the replay cache.
6667c478bd9Sstevel@tonic-gate      */
6677c478bd9Sstevel@tonic-gate     if ((retval = kdc_initialize_rcache(kcontext, rcname))) {
66856a424ccSmp153739 	com_err(argv[0], retval, gettext("while initializing KDC replay cache '%s'"),
66956a424ccSmp153739 		rcname);
6707c478bd9Sstevel@tonic-gate 	exit(1);
6717c478bd9Sstevel@tonic-gate     }
6727c478bd9Sstevel@tonic-gate #endif
6737c478bd9Sstevel@tonic-gate 
6747c478bd9Sstevel@tonic-gate     /* Ensure that this is set for our first request. */
6757c478bd9Sstevel@tonic-gate     kdc_active_realm = kdc_realmlist[0];
676*7c64d375Smp153739     if (lrealm)
677*7c64d375Smp153739 	free(lrealm);
6787c478bd9Sstevel@tonic-gate     if (default_udp_ports)
6797c478bd9Sstevel@tonic-gate 	free(default_udp_ports);
6807c478bd9Sstevel@tonic-gate     if (default_tcp_ports)
6817c478bd9Sstevel@tonic-gate 	free(default_tcp_ports);
68254925bf6Swillf     if (db_args)
68354925bf6Swillf 	free(db_args);
68454925bf6Swillf     if (db_name)
68554925bf6Swillf 	free(db_name);
6867c478bd9Sstevel@tonic-gate 
6877c478bd9Sstevel@tonic-gate     return;
6887c478bd9Sstevel@tonic-gate }
6897c478bd9Sstevel@tonic-gate 
6907c478bd9Sstevel@tonic-gate void
69156a424ccSmp153739 finish_realms(char *prog)
6927c478bd9Sstevel@tonic-gate {
6937c478bd9Sstevel@tonic-gate     int i;
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate     for (i = 0; i < kdc_numrealms; i++) {
6967c478bd9Sstevel@tonic-gate 	finish_realm(kdc_realmlist[i]);
6977c478bd9Sstevel@tonic-gate 	kdc_realmlist[i] = 0;
6987c478bd9Sstevel@tonic-gate     }
6997c478bd9Sstevel@tonic-gate }
7007c478bd9Sstevel@tonic-gate 
7017c478bd9Sstevel@tonic-gate /*
7027c478bd9Sstevel@tonic-gate  outline:
7037c478bd9Sstevel@tonic-gate 
7047c478bd9Sstevel@tonic-gate  process args & setup
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate  initialize database access (fetch master key, open DB)
7077c478bd9Sstevel@tonic-gate 
7087c478bd9Sstevel@tonic-gate  initialize network
7097c478bd9Sstevel@tonic-gate 
7107c478bd9Sstevel@tonic-gate  loop:
7117c478bd9Sstevel@tonic-gate  	listen for packet
7127c478bd9Sstevel@tonic-gate 
7137c478bd9Sstevel@tonic-gate 	determine packet type, dispatch to handling routine
7147c478bd9Sstevel@tonic-gate 		(AS or TGS (or V4?))
7157c478bd9Sstevel@tonic-gate 
7167c478bd9Sstevel@tonic-gate 	reflect response
7177c478bd9Sstevel@tonic-gate 
7187c478bd9Sstevel@tonic-gate 	exit on signal
7197c478bd9Sstevel@tonic-gate 
7207c478bd9Sstevel@tonic-gate  clean up secrets, close db
7217c478bd9Sstevel@tonic-gate 
7227c478bd9Sstevel@tonic-gate  shut down network
7237c478bd9Sstevel@tonic-gate 
7247c478bd9Sstevel@tonic-gate  exit
7257c478bd9Sstevel@tonic-gate  */
7267c478bd9Sstevel@tonic-gate 
72756a424ccSmp153739 int main(int argc, char **argv)
7287c478bd9Sstevel@tonic-gate {
7297c478bd9Sstevel@tonic-gate     krb5_error_code	retval;
7307c478bd9Sstevel@tonic-gate     krb5_context	kcontext;
7317c478bd9Sstevel@tonic-gate     int errout = 0;
7327c478bd9Sstevel@tonic-gate 
733*7c64d375Smp153739     krb5_boolean log_stderr_set;
734*7c64d375Smp153739 
7357c478bd9Sstevel@tonic-gate     (void) setlocale(LC_ALL, "");
7367c478bd9Sstevel@tonic-gate 
7377c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)		/* Should be defined by cc -D */
7387c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN	"KRB5KDC_TEST"	/* Use this only if it weren't */
7397c478bd9Sstevel@tonic-gate #endif
7407c478bd9Sstevel@tonic-gate 
7417c478bd9Sstevel@tonic-gate     (void) textdomain(TEXT_DOMAIN);
7427c478bd9Sstevel@tonic-gate 
7437c478bd9Sstevel@tonic-gate     if (strrchr(argv[0], '/'))
7447c478bd9Sstevel@tonic-gate 	argv[0] = strrchr(argv[0], '/')+1;
7457c478bd9Sstevel@tonic-gate 
7467c478bd9Sstevel@tonic-gate     if (!(kdc_realmlist = (kdc_realm_t **) malloc(sizeof(kdc_realm_t *) *
7477c478bd9Sstevel@tonic-gate 						  KRB5_KDC_MAX_REALMS))) {
7487c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("%s: cannot get memory for realm list\n"), argv[0]);
7497c478bd9Sstevel@tonic-gate 	exit(1);
7507c478bd9Sstevel@tonic-gate     }
7517c478bd9Sstevel@tonic-gate     memset((char *) kdc_realmlist, 0,
7527c478bd9Sstevel@tonic-gate 	   (size_t) (sizeof(kdc_realm_t *) * KRB5_KDC_MAX_REALMS));
7537c478bd9Sstevel@tonic-gate 
7547c478bd9Sstevel@tonic-gate     /*
7557c478bd9Sstevel@tonic-gate      * A note about Kerberos contexts: This context, "kcontext", is used
7567c478bd9Sstevel@tonic-gate      * for the KDC operations, i.e. setup, network connection and error
7577c478bd9Sstevel@tonic-gate      * reporting.  The per-realm operations use the "realm_context"
7587c478bd9Sstevel@tonic-gate      * associated with each realm.
7597c478bd9Sstevel@tonic-gate      */
76054925bf6Swillf     retval = krb5int_init_context_kdc(&kcontext);
7617c478bd9Sstevel@tonic-gate     if (retval) {
7627c478bd9Sstevel@tonic-gate 	    com_err(argv[0], retval, gettext("while initializing krb5"));
7637c478bd9Sstevel@tonic-gate 	    exit(1);
7647c478bd9Sstevel@tonic-gate     }
7657c478bd9Sstevel@tonic-gate     krb5_klog_init(kcontext, "kdc", argv[0], 1);
766*7c64d375Smp153739 
767*7c64d375Smp153739     /*
768*7c64d375Smp153739      * Solaris Kerberos:
769*7c64d375Smp153739      * In the early stages of krb5kdc it is desirable to log error messages
770*7c64d375Smp153739      * to stderr as well as any other logging locations specified in config
771*7c64d375Smp153739      * files.
772*7c64d375Smp153739      */
773*7c64d375Smp153739      log_stderr_set = krb5_klog_logging_to_stderr();
774*7c64d375Smp153739      if (log_stderr_set != TRUE) {
775*7c64d375Smp153739      	krb5_klog_add_stderr();
776*7c64d375Smp153739      }
777*7c64d375Smp153739 
7787c478bd9Sstevel@tonic-gate     /* initialize_kdc5_error_table();  SUNWresync121 XXX */
7797c478bd9Sstevel@tonic-gate 
7807c478bd9Sstevel@tonic-gate     /*
7817c478bd9Sstevel@tonic-gate      * Scan through the argument list
7827c478bd9Sstevel@tonic-gate      */
7837c478bd9Sstevel@tonic-gate     initialize_realms(kcontext, argc, argv);
7847c478bd9Sstevel@tonic-gate 
7857c478bd9Sstevel@tonic-gate     setup_signal_handlers();
7867c478bd9Sstevel@tonic-gate 
78756a424ccSmp153739     retval = setup_sam();
78856a424ccSmp153739     if (retval) {
7897c478bd9Sstevel@tonic-gate 	com_err(argv[0], retval, gettext("while initializing SAM"));
7907c478bd9Sstevel@tonic-gate 	finish_realms(argv[0]);
7917c478bd9Sstevel@tonic-gate 	return 1;
7927c478bd9Sstevel@tonic-gate     }
7937c478bd9Sstevel@tonic-gate 
7947c478bd9Sstevel@tonic-gate     if ((retval = setup_network(argv[0]))) {
7957c478bd9Sstevel@tonic-gate 	com_err(argv[0], retval, gettext("while initializing network"));
7967c478bd9Sstevel@tonic-gate 	finish_realms(argv[0]);
7977c478bd9Sstevel@tonic-gate 	return 1;
7987c478bd9Sstevel@tonic-gate     }
799*7c64d375Smp153739 
800*7c64d375Smp153739     /* Solaris Kerberos: Remove the extra stderr logging */
801*7c64d375Smp153739     if (log_stderr_set != TRUE)
802*7c64d375Smp153739 	krb5_klog_remove_stderr();
803*7c64d375Smp153739 
804*7c64d375Smp153739     /*
805*7c64d375Smp153739      * Solaris Kerberos:
806*7c64d375Smp153739      * List the logs (FILE, STDERR, etc) which are currently being
807*7c64d375Smp153739      * logged to and print that to stderr. Useful when trying to
808*7c64d375Smp153739      * track down a failure via SMF.
809*7c64d375Smp153739      */
810*7c64d375Smp153739     if (retval = krb5_klog_list_logs(argv[0])) {
811*7c64d375Smp153739 	com_err(argv[0], retval, gettext("while listing logs"));
812*7c64d375Smp153739 	if (log_stderr_set != TRUE) {
813*7c64d375Smp153739 		fprintf(stderr, gettext("%s: %s while listing logs\n"),
814*7c64d375Smp153739 		    argv[0], error_message(retval));
815*7c64d375Smp153739 	}
816*7c64d375Smp153739     }
817*7c64d375Smp153739 
8187c478bd9Sstevel@tonic-gate     if (!nofork && daemon(0, 0)) {
8197c478bd9Sstevel@tonic-gate 	com_err(argv[0], errno, gettext("while detaching from tty"));
820*7c64d375Smp153739 	if (log_stderr_set != TRUE) {
821*7c64d375Smp153739 		fprintf(stderr, gettext("%s: %s while detaching from tty\n"),
822*7c64d375Smp153739 		  argv[0], strerror(errno));
823*7c64d375Smp153739 	}
8247c478bd9Sstevel@tonic-gate 	finish_realms(argv[0]);
8257c478bd9Sstevel@tonic-gate 	return 1;
8267c478bd9Sstevel@tonic-gate     }
8277c478bd9Sstevel@tonic-gate     if (retval = krb5_klog_syslog(LOG_INFO, "commencing operation")) {
8287c478bd9Sstevel@tonic-gate 	com_err(argv[0], retval, gettext("while logging message"));
8297c478bd9Sstevel@tonic-gate 	errout++;
8307c478bd9Sstevel@tonic-gate 	};
8317c478bd9Sstevel@tonic-gate 
8327c478bd9Sstevel@tonic-gate     if ((retval = listen_and_process(argv[0]))) {
8337c478bd9Sstevel@tonic-gate 	com_err(argv[0], retval, gettext("while processing network requests"));
8347c478bd9Sstevel@tonic-gate 	errout++;
8357c478bd9Sstevel@tonic-gate     }
8367c478bd9Sstevel@tonic-gate     if ((retval = closedown_network(argv[0]))) {
8377c478bd9Sstevel@tonic-gate 	com_err(argv[0], retval, gettext("while shutting down network"));
8387c478bd9Sstevel@tonic-gate 	errout++;
8397c478bd9Sstevel@tonic-gate     }
8407c478bd9Sstevel@tonic-gate     krb5_klog_syslog(LOG_INFO, "shutting down");
8417c478bd9Sstevel@tonic-gate     krb5_klog_close(kdc_context);
8427c478bd9Sstevel@tonic-gate     finish_realms(argv[0]);
84356a424ccSmp153739     if (kdc_realmlist)
84456a424ccSmp153739       free(kdc_realmlist);
84556a424ccSmp153739 #ifdef USE_RCACHE
84656a424ccSmp153739     (void) krb5_rc_close(kcontext, kdc_rcache);
84756a424ccSmp153739 #endif
84856a424ccSmp153739 #ifndef NOCACHE
84956a424ccSmp153739     kdc_free_lookaside(kcontext);
85056a424ccSmp153739 #endif
8517c478bd9Sstevel@tonic-gate     krb5_free_context(kcontext);
8527c478bd9Sstevel@tonic-gate     return errout;
8537c478bd9Sstevel@tonic-gate }
85456a424ccSmp153739 
85556a424ccSmp153739 
85656a424ccSmp153739 
85756a424ccSmp153739 
858