xref: /onnv-gate/usr/src/cmd/krb5/krb5kdc/main.c (revision 7934:6aeeafc994de)
10Sstevel@tonic-gate /*
26426Smp153739  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate 
60Sstevel@tonic-gate 
70Sstevel@tonic-gate /*
80Sstevel@tonic-gate  * kdc/main.c
90Sstevel@tonic-gate  *
100Sstevel@tonic-gate  * Copyright 1990,2001 by the Massachusetts Institute of Technology.
110Sstevel@tonic-gate  *
120Sstevel@tonic-gate  * Export of this software from the United States of America may
130Sstevel@tonic-gate  *   require a specific license from the United States Government.
140Sstevel@tonic-gate  *   It is the responsibility of any person or organization contemplating
150Sstevel@tonic-gate  *   export to obtain such a license before exporting.
160Sstevel@tonic-gate  *
170Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
180Sstevel@tonic-gate  * distribute this software and its documentation for any purpose and
190Sstevel@tonic-gate  * without fee is hereby granted, provided that the above copyright
200Sstevel@tonic-gate  * notice appear in all copies and that both that copyright notice and
210Sstevel@tonic-gate  * this permission notice appear in supporting documentation, and that
220Sstevel@tonic-gate  * the name of M.I.T. not be used in advertising or publicity pertaining
230Sstevel@tonic-gate  * to distribution of the software without specific, written prior
240Sstevel@tonic-gate  * permission.  Furthermore if you modify this software you must label
250Sstevel@tonic-gate  * your software as modified software and not distribute it in such a
260Sstevel@tonic-gate  * fashion that it might be confused with the original M.I.T. software.
270Sstevel@tonic-gate  * M.I.T. makes no representations about the suitability of
280Sstevel@tonic-gate  * this software for any purpose.  It is provided "as is" without express
290Sstevel@tonic-gate  * or implied warranty.
300Sstevel@tonic-gate  *
310Sstevel@tonic-gate  *
320Sstevel@tonic-gate  * Main procedure body for the KDC server process.
330Sstevel@tonic-gate  */
340Sstevel@tonic-gate 
350Sstevel@tonic-gate #include <stdio.h>
360Sstevel@tonic-gate #include <syslog.h>
370Sstevel@tonic-gate #include <signal.h>
380Sstevel@tonic-gate #include <errno.h>
390Sstevel@tonic-gate #include <netdb.h>
400Sstevel@tonic-gate 
410Sstevel@tonic-gate #include "k5-int.h"
420Sstevel@tonic-gate #include "com_err.h"
430Sstevel@tonic-gate #include "adm.h"
440Sstevel@tonic-gate #include "adm_proto.h"
450Sstevel@tonic-gate #include "kdc_util.h"
460Sstevel@tonic-gate #include "extern.h"
470Sstevel@tonic-gate #include "kdc5_err.h"
480Sstevel@tonic-gate #include <libintl.h>
490Sstevel@tonic-gate #include <locale.h>
500Sstevel@tonic-gate 
510Sstevel@tonic-gate #ifdef HAVE_NETINET_IN_H
520Sstevel@tonic-gate #include <netinet/in.h>
530Sstevel@tonic-gate #endif
540Sstevel@tonic-gate 
552881Smp153739 #ifdef KRB5_KRB4_COMPAT
562881Smp153739 #include <des.h>
572881Smp153739 #endif
582881Smp153739 
592881Smp153739 #if defined(NEED_DAEMON_PROTO)
602881Smp153739 extern int daemon(int, int);
612881Smp153739 #endif
620Sstevel@tonic-gate 
63781Sgtb void usage (char *);
640Sstevel@tonic-gate 
65781Sgtb krb5_sigtype request_exit (int);
66781Sgtb krb5_sigtype request_hup  (int);
670Sstevel@tonic-gate 
68781Sgtb void setup_signal_handlers (void);
690Sstevel@tonic-gate 
70781Sgtb krb5_error_code setup_sam (void);
710Sstevel@tonic-gate 
72781Sgtb void initialize_realms (krb5_context, int, char **);
730Sstevel@tonic-gate 
74781Sgtb void finish_realms (char *);
750Sstevel@tonic-gate 
760Sstevel@tonic-gate static int nofork = 0;
770Sstevel@tonic-gate static int rkey_init_done = 0;
780Sstevel@tonic-gate 
790Sstevel@tonic-gate /* Solaris Kerberos: global here that other functions access */
800Sstevel@tonic-gate int max_tcp_data_connections;
810Sstevel@tonic-gate 
820Sstevel@tonic-gate #ifdef POSIX_SIGNALS
830Sstevel@tonic-gate static struct sigaction s_action;
840Sstevel@tonic-gate #endif /* POSIX_SIGNALS */
850Sstevel@tonic-gate 
860Sstevel@tonic-gate #define	KRB5_KDC_MAX_REALMS	32
870Sstevel@tonic-gate 
880Sstevel@tonic-gate /*
890Sstevel@tonic-gate  * Find the realm entry for a given realm.
900Sstevel@tonic-gate  */
910Sstevel@tonic-gate kdc_realm_t *
find_realm_data(char * rname,krb5_ui_4 rsize)922881Smp153739 find_realm_data(char *rname, krb5_ui_4 rsize)
930Sstevel@tonic-gate {
940Sstevel@tonic-gate     int i;
950Sstevel@tonic-gate     for (i=0; i<kdc_numrealms; i++) {
960Sstevel@tonic-gate 	if ((rsize == strlen(kdc_realmlist[i]->realm_name)) &&
970Sstevel@tonic-gate 	    !strncmp(rname, kdc_realmlist[i]->realm_name, rsize))
980Sstevel@tonic-gate 	    return(kdc_realmlist[i]);
990Sstevel@tonic-gate     }
1000Sstevel@tonic-gate     return((kdc_realm_t *) NULL);
1010Sstevel@tonic-gate }
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate krb5_error_code
setup_server_realm(krb5_principal sprinc)1042881Smp153739 setup_server_realm(krb5_principal sprinc)
1050Sstevel@tonic-gate {
1060Sstevel@tonic-gate     krb5_error_code	kret;
1070Sstevel@tonic-gate     kdc_realm_t		*newrealm;
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate     kret = 0;
1100Sstevel@tonic-gate     if (kdc_numrealms > 1) {
1110Sstevel@tonic-gate 	if (!(newrealm = find_realm_data(sprinc->realm.data,
1120Sstevel@tonic-gate 					 (krb5_ui_4) sprinc->realm.length)))
1130Sstevel@tonic-gate 	    kret = ENOENT;
1140Sstevel@tonic-gate 	else
1150Sstevel@tonic-gate 	    kdc_active_realm = newrealm;
1160Sstevel@tonic-gate     }
1170Sstevel@tonic-gate     else
1180Sstevel@tonic-gate 	kdc_active_realm = kdc_realmlist[0];
1190Sstevel@tonic-gate     return(kret);
1200Sstevel@tonic-gate }
1210Sstevel@tonic-gate 
1220Sstevel@tonic-gate static void
finish_realm(kdc_realm_t * rdp)1232881Smp153739 finish_realm(kdc_realm_t *rdp)
1240Sstevel@tonic-gate {
1250Sstevel@tonic-gate     if (rdp->realm_dbname)
1260Sstevel@tonic-gate 	free(rdp->realm_dbname);
1270Sstevel@tonic-gate     if (rdp->realm_mpname)
1280Sstevel@tonic-gate 	free(rdp->realm_mpname);
1290Sstevel@tonic-gate     if (rdp->realm_stash)
1300Sstevel@tonic-gate 	free(rdp->realm_stash);
1310Sstevel@tonic-gate     if (rdp->realm_ports)
1320Sstevel@tonic-gate 	free(rdp->realm_ports);
1330Sstevel@tonic-gate     if (rdp->realm_tcp_ports)
1340Sstevel@tonic-gate 	free(rdp->realm_tcp_ports);
1350Sstevel@tonic-gate     if (rdp->realm_keytab)
1360Sstevel@tonic-gate 	krb5_kt_close(rdp->realm_context, rdp->realm_keytab);
1370Sstevel@tonic-gate     if (rdp->realm_context) {
1380Sstevel@tonic-gate 	if (rdp->realm_mprinc)
1390Sstevel@tonic-gate 	    krb5_free_principal(rdp->realm_context, rdp->realm_mprinc);
1400Sstevel@tonic-gate 	if (rdp->realm_mkey.length && rdp->realm_mkey.contents) {
1410Sstevel@tonic-gate 	    memset(rdp->realm_mkey.contents, 0, rdp->realm_mkey.length);
1420Sstevel@tonic-gate 	    free(rdp->realm_mkey.contents);
1430Sstevel@tonic-gate 	}
1440Sstevel@tonic-gate 	krb5_db_fini(rdp->realm_context);
1450Sstevel@tonic-gate 	if (rdp->realm_tgsprinc)
1460Sstevel@tonic-gate 	    krb5_free_principal(rdp->realm_context, rdp->realm_tgsprinc);
1470Sstevel@tonic-gate 	krb5_free_context(rdp->realm_context);
1480Sstevel@tonic-gate     }
1492881Smp153739     memset((char *) rdp, 0, sizeof(*rdp));
1500Sstevel@tonic-gate     free(rdp);
1510Sstevel@tonic-gate }
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate /*
1540Sstevel@tonic-gate  * Initialize a realm control structure from the alternate profile or from
1550Sstevel@tonic-gate  * the specified defaults.
1560Sstevel@tonic-gate  *
1570Sstevel@tonic-gate  * After we're complete here, the essence of the realm is embodied in the
1580Sstevel@tonic-gate  * realm data and we should be all set to begin operation for that realm.
1590Sstevel@tonic-gate  */
1600Sstevel@tonic-gate static krb5_error_code
init_realm(krb5_context kcontext,char * progname,kdc_realm_t * rdp,char * realm,char * def_mpname,krb5_enctype def_enctype,char * def_udp_ports,char * def_tcp_ports,krb5_boolean def_manual,char ** db_args)1616426Smp153739 init_realm(krb5_context kcontext, char *progname, kdc_realm_t *rdp, char *realm,
1622881Smp153739 	   char *def_mpname, krb5_enctype def_enctype, char *def_udp_ports,
1634960Swillf 	   char *def_tcp_ports, krb5_boolean def_manual, char **db_args)
1640Sstevel@tonic-gate {
1650Sstevel@tonic-gate     krb5_error_code	kret;
1660Sstevel@tonic-gate     krb5_boolean	manual;
1670Sstevel@tonic-gate     krb5_realm_params	*rparams;
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate     memset((char *) rdp, 0, sizeof(kdc_realm_t));
1700Sstevel@tonic-gate     if (!realm) {
1710Sstevel@tonic-gate 	kret = EINVAL;
1720Sstevel@tonic-gate 	goto whoops;
1730Sstevel@tonic-gate     }
1740Sstevel@tonic-gate 
1750Sstevel@tonic-gate     rdp->realm_name = realm;
1764960Swillf     kret = krb5int_init_context_kdc(&rdp->realm_context);
1770Sstevel@tonic-gate     if (kret) {
1780Sstevel@tonic-gate 	com_err(progname, kret, gettext("while getting context for realm %s"),
1790Sstevel@tonic-gate 		realm);
1800Sstevel@tonic-gate 	goto whoops;
1810Sstevel@tonic-gate     }
1820Sstevel@tonic-gate 
1836426Smp153739     /*
1846426Smp153739      * Solaris Kerberos:
1856426Smp153739      * Set the current context to that of the realm being init'ed
1866426Smp153739      */
1876426Smp153739     krb5_klog_set_context(rdp->realm_context);
1886426Smp153739 
1890Sstevel@tonic-gate     kret = krb5_read_realm_params(rdp->realm_context, rdp->realm_name,
190*7934SMark.Phalan@Sun.COM 				  &rparams);
1910Sstevel@tonic-gate     if (kret) {
1920Sstevel@tonic-gate 	com_err(progname, kret, gettext("while reading realm parameters"));
1930Sstevel@tonic-gate 	goto whoops;
1940Sstevel@tonic-gate     }
1952881Smp153739 
1960Sstevel@tonic-gate     /* Handle profile file name */
1970Sstevel@tonic-gate     if (rparams && rparams->realm_profile)
1980Sstevel@tonic-gate 	rdp->realm_profile = strdup(rparams->realm_profile);
1990Sstevel@tonic-gate 
2000Sstevel@tonic-gate     /* Handle master key name */
2010Sstevel@tonic-gate     if (rparams && rparams->realm_mkey_name)
2020Sstevel@tonic-gate 	rdp->realm_mpname = strdup(rparams->realm_mkey_name);
2030Sstevel@tonic-gate     else
2040Sstevel@tonic-gate 	rdp->realm_mpname = (def_mpname) ? strdup(def_mpname) :
2050Sstevel@tonic-gate 	    strdup(KRB5_KDB_M_NAME);
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate     /* Handle KDC ports */
2080Sstevel@tonic-gate     if (rparams && rparams->realm_kdc_ports)
2090Sstevel@tonic-gate 	rdp->realm_ports = strdup(rparams->realm_kdc_ports);
2100Sstevel@tonic-gate     else
2110Sstevel@tonic-gate 	rdp->realm_ports = strdup(def_udp_ports);
2120Sstevel@tonic-gate     if (rparams && rparams->realm_kdc_tcp_ports)
2130Sstevel@tonic-gate 	rdp->realm_tcp_ports = strdup(rparams->realm_kdc_tcp_ports);
2140Sstevel@tonic-gate     else
2150Sstevel@tonic-gate 	rdp->realm_tcp_ports = strdup(def_tcp_ports);
2160Sstevel@tonic-gate 
2170Sstevel@tonic-gate     /* Handle stash file */
2180Sstevel@tonic-gate     if (rparams && rparams->realm_stash_file) {
2190Sstevel@tonic-gate 	rdp->realm_stash = strdup(rparams->realm_stash_file);
2200Sstevel@tonic-gate 	manual = FALSE;
2210Sstevel@tonic-gate     } else
2220Sstevel@tonic-gate 	manual = def_manual;
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate     /* Handle master key type */
2250Sstevel@tonic-gate     if (rparams && rparams->realm_enctype_valid)
2260Sstevel@tonic-gate 	rdp->realm_mkey.enctype = (krb5_enctype) rparams->realm_enctype;
2270Sstevel@tonic-gate     else
2280Sstevel@tonic-gate 	rdp->realm_mkey.enctype = manual ? def_enctype : ENCTYPE_UNKNOWN;
2292881Smp153739 
2302881Smp153739     /* Handle reject-bad-transit flag */
2312881Smp153739     if (rparams && rparams->realm_reject_bad_transit_valid)
2322881Smp153739 	rdp->realm_reject_bad_transit = rparams->realm_reject_bad_transit;
2332881Smp153739     else
2342881Smp153739 	rdp->realm_reject_bad_transit = 1;
2350Sstevel@tonic-gate 
2360Sstevel@tonic-gate     /* Handle ticket maximum life */
2372881Smp153739     rdp->realm_maxlife = (rparams && rparams->realm_max_life_valid) ?
2382881Smp153739 	rparams->realm_max_life : KRB5_KDB_MAX_LIFE;
2390Sstevel@tonic-gate 
2400Sstevel@tonic-gate     /* Handle ticket renewable maximum life */
2412881Smp153739     rdp->realm_maxrlife = (rparams && rparams->realm_max_rlife_valid) ?
2422881Smp153739 	rparams->realm_max_rlife : KRB5_KDB_MAX_RLIFE;
2430Sstevel@tonic-gate 
2440Sstevel@tonic-gate     if (rparams)
2450Sstevel@tonic-gate 	krb5_free_realm_params(rdp->realm_context, rparams);
2460Sstevel@tonic-gate 
2470Sstevel@tonic-gate     /*
2480Sstevel@tonic-gate      * We've got our parameters, now go and setup our realm context.
2490Sstevel@tonic-gate      */
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate     /* Set the default realm of this context */
2520Sstevel@tonic-gate     if ((kret = krb5_set_default_realm(rdp->realm_context, realm))) {
2530Sstevel@tonic-gate 	com_err(progname, kret, gettext("while setting default realm to %s"),
2540Sstevel@tonic-gate 		realm);
2550Sstevel@tonic-gate 	goto whoops;
2560Sstevel@tonic-gate     }
2570Sstevel@tonic-gate 
2584960Swillf     /* first open the database  before doing anything */
2594960Swillf #ifdef KRBCONF_KDC_MODIFIES_KDB
2604960Swillf     if ((kret = krb5_db_open(rdp->realm_context, db_args,
2614960Swillf 			     KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_KDC))) {
2624960Swillf #else
2634960Swillf     if ((kret = krb5_db_open(rdp->realm_context, db_args,
2644960Swillf 			     KRB5_KDB_OPEN_RO | KRB5_KDB_SRV_TYPE_KDC))) {
2654960Swillf #endif
2666426Smp153739 	/*
2676426Smp153739 	 * Solaris Kerberos:
2686426Smp153739 	 * Make sure that error messages are printed using gettext
2696426Smp153739 	 */
2704960Swillf 	com_err(progname, kret,
2716426Smp153739 	    gettext("while initializing database for realm %s"), realm);
2724960Swillf 	goto whoops;
2734960Swillf     }
2744960Swillf 
2750Sstevel@tonic-gate     /* Assemble and parse the master key name */
2760Sstevel@tonic-gate     if ((kret = krb5_db_setup_mkey_name(rdp->realm_context, rdp->realm_mpname,
2770Sstevel@tonic-gate 					rdp->realm_name, (char **) NULL,
2780Sstevel@tonic-gate 					&rdp->realm_mprinc))) {
2790Sstevel@tonic-gate 	com_err(progname, kret,
2800Sstevel@tonic-gate 		gettext("while setting up master key name %s for realm %s"),
2810Sstevel@tonic-gate 		rdp->realm_mpname, realm);
2820Sstevel@tonic-gate 	goto whoops;
2830Sstevel@tonic-gate     }
2840Sstevel@tonic-gate 
2850Sstevel@tonic-gate     /*
2860Sstevel@tonic-gate      * Get the master key.
2870Sstevel@tonic-gate      */
2880Sstevel@tonic-gate     if ((kret = krb5_db_fetch_mkey(rdp->realm_context, rdp->realm_mprinc,
2890Sstevel@tonic-gate 				   rdp->realm_mkey.enctype, manual,
2900Sstevel@tonic-gate 				   FALSE, rdp->realm_stash,
2910Sstevel@tonic-gate 				   0, &rdp->realm_mkey))) {
2920Sstevel@tonic-gate 	com_err(progname, kret,
2930Sstevel@tonic-gate 		gettext("while fetching master key %s for realm %s"),
2940Sstevel@tonic-gate 		rdp->realm_mpname, realm);
2950Sstevel@tonic-gate 	goto whoops;
2960Sstevel@tonic-gate     }
2970Sstevel@tonic-gate 
2980Sstevel@tonic-gate     /* Verify the master key */
2990Sstevel@tonic-gate     if ((kret = krb5_db_verify_master_key(rdp->realm_context,
3000Sstevel@tonic-gate 					  rdp->realm_mprinc,
3010Sstevel@tonic-gate 					  &rdp->realm_mkey))) {
3020Sstevel@tonic-gate 	com_err(progname, kret,
3030Sstevel@tonic-gate 		gettext("while verifying master key for realm %s"),
3040Sstevel@tonic-gate 		realm);
3050Sstevel@tonic-gate 	goto whoops;
3060Sstevel@tonic-gate     }
3070Sstevel@tonic-gate 
3080Sstevel@tonic-gate     if ((kret = krb5_db_set_mkey(rdp->realm_context, &rdp->realm_mkey))) {
3090Sstevel@tonic-gate 	com_err(progname, kret,
3100Sstevel@tonic-gate 		gettext("while processing master key for realm %s"),
3110Sstevel@tonic-gate 		realm);
3120Sstevel@tonic-gate 	goto whoops;
3130Sstevel@tonic-gate     }
3140Sstevel@tonic-gate 
3150Sstevel@tonic-gate     /* Set up the keytab */
3162881Smp153739     if ((kret = krb5_ktkdb_resolve(rdp->realm_context, NULL,
3170Sstevel@tonic-gate 				   &rdp->realm_keytab))) {
3180Sstevel@tonic-gate 	com_err(progname, kret,
3190Sstevel@tonic-gate 		gettext("while resolving kdb keytab for realm %s"),
3200Sstevel@tonic-gate 		realm);
3210Sstevel@tonic-gate 	goto whoops;
3220Sstevel@tonic-gate     }
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate     /* Preformat the TGS name */
3250Sstevel@tonic-gate     if ((kret = krb5_build_principal(rdp->realm_context, &rdp->realm_tgsprinc,
3260Sstevel@tonic-gate 				     strlen(realm), realm, KRB5_TGS_NAME,
3270Sstevel@tonic-gate 				     realm, (char *) NULL))) {
3280Sstevel@tonic-gate 	com_err(progname, kret,
3290Sstevel@tonic-gate 		gettext("while building TGS name for realm %s"),
3300Sstevel@tonic-gate 		realm);
3310Sstevel@tonic-gate 	goto whoops;
3320Sstevel@tonic-gate     }
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate     if (!rkey_init_done) {
3350Sstevel@tonic-gate 	krb5_data seed;
3360Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
3370Sstevel@tonic-gate 	krb5_keyblock temp_key;
3380Sstevel@tonic-gate #endif
3390Sstevel@tonic-gate 	/*
3400Sstevel@tonic-gate 	 * If all that worked, then initialize the random key
3410Sstevel@tonic-gate 	 * generators.
3420Sstevel@tonic-gate 	 */
3430Sstevel@tonic-gate 
3440Sstevel@tonic-gate 	seed.length = rdp->realm_mkey.length;
3450Sstevel@tonic-gate 	seed.data = (char *)rdp->realm_mkey.contents;
3462881Smp153739 /* SUNW14resync - XXX */
3472881Smp153739 #if 0
3482881Smp153739 	if ((kret = krb5_c_random_add_entropy(rdp->realm_context,
3492881Smp153739 					     KRB5_C_RANDSOURCE_TRUSTEDPARTY, &seed)))
3500Sstevel@tonic-gate 	    goto whoops;
3512881Smp153739 #endif
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
3540Sstevel@tonic-gate 	if ((kret = krb5_c_make_random_key(rdp->realm_context,
3550Sstevel@tonic-gate 					   ENCTYPE_DES_CBC_CRC, &temp_key))) {
3560Sstevel@tonic-gate 	    com_err(progname, kret,
3570Sstevel@tonic-gate 		    "while initializing V4 random key generator");
3580Sstevel@tonic-gate 	    goto whoops;
3590Sstevel@tonic-gate 	}
3600Sstevel@tonic-gate 
3610Sstevel@tonic-gate 	(void) des_init_random_number_generator(temp_key.contents);
3620Sstevel@tonic-gate 	krb5_free_keyblock_contents(rdp->realm_context, &temp_key);
3630Sstevel@tonic-gate #endif
3640Sstevel@tonic-gate 	rkey_init_done = 1;
3650Sstevel@tonic-gate     }
3660Sstevel@tonic-gate  whoops:
3670Sstevel@tonic-gate     /*
3680Sstevel@tonic-gate      * If we choked, then clean up any dirt we may have dropped on the floor.
3690Sstevel@tonic-gate      */
3700Sstevel@tonic-gate     if (kret) {
3712881Smp153739 
3720Sstevel@tonic-gate 	finish_realm(rdp);
3730Sstevel@tonic-gate     }
3746426Smp153739 
3756426Smp153739     /*
3766426Smp153739      * Solaris Kerberos:
3776426Smp153739      * Set the current context back to the general context
3786426Smp153739      */
3796426Smp153739     krb5_klog_set_context(kcontext);
3806426Smp153739 
3810Sstevel@tonic-gate     return(kret);
3820Sstevel@tonic-gate }
3830Sstevel@tonic-gate 
3840Sstevel@tonic-gate krb5_sigtype
3852881Smp153739 request_exit(int signo)
3860Sstevel@tonic-gate {
3870Sstevel@tonic-gate     signal_requests_exit = 1;
3880Sstevel@tonic-gate 
3890Sstevel@tonic-gate #ifdef POSIX_SIGTYPE
3900Sstevel@tonic-gate     return;
3910Sstevel@tonic-gate #else
3920Sstevel@tonic-gate     return(0);
3930Sstevel@tonic-gate #endif
3940Sstevel@tonic-gate }
3950Sstevel@tonic-gate 
3960Sstevel@tonic-gate krb5_sigtype
3972881Smp153739 request_hup(int signo)
3980Sstevel@tonic-gate {
3990Sstevel@tonic-gate     signal_requests_hup = 1;
4000Sstevel@tonic-gate 
4010Sstevel@tonic-gate #ifdef POSIX_SIGTYPE
4020Sstevel@tonic-gate     return;
4030Sstevel@tonic-gate #else
4040Sstevel@tonic-gate     return(0);
4050Sstevel@tonic-gate #endif
4060Sstevel@tonic-gate }
4070Sstevel@tonic-gate 
4080Sstevel@tonic-gate void
4092881Smp153739 setup_signal_handlers(void)
4100Sstevel@tonic-gate {
4110Sstevel@tonic-gate #ifdef POSIX_SIGNALS
4120Sstevel@tonic-gate     (void) sigemptyset(&s_action.sa_mask);
4130Sstevel@tonic-gate     s_action.sa_flags = 0;
4140Sstevel@tonic-gate     s_action.sa_handler = request_exit;
4150Sstevel@tonic-gate     (void) sigaction(SIGINT, &s_action, (struct sigaction *) NULL);
4160Sstevel@tonic-gate     (void) sigaction(SIGTERM, &s_action, (struct sigaction *) NULL);
4170Sstevel@tonic-gate     s_action.sa_handler = request_hup;
4180Sstevel@tonic-gate     (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL);
4194960Swillf     s_action.sa_handler = SIG_IGN;
4204960Swillf     (void) sigaction(SIGPIPE, &s_action, (struct sigaction *) NULL);
4210Sstevel@tonic-gate #else  /* POSIX_SIGNALS */
4220Sstevel@tonic-gate     signal(SIGINT, request_exit);
4230Sstevel@tonic-gate     signal(SIGTERM, request_exit);
4240Sstevel@tonic-gate     signal(SIGHUP, request_hup);
4254960Swillf     signal(SIGPIPE, SIG_IGN);
4260Sstevel@tonic-gate #endif /* POSIX_SIGNALS */
4270Sstevel@tonic-gate 
4280Sstevel@tonic-gate     return;
4290Sstevel@tonic-gate }
4300Sstevel@tonic-gate 
4310Sstevel@tonic-gate krb5_error_code
4322881Smp153739 setup_sam(void)
4330Sstevel@tonic-gate {
4340Sstevel@tonic-gate     return krb5_c_make_random_key(kdc_context, ENCTYPE_DES_CBC_MD5, &psr_key);
4350Sstevel@tonic-gate }
4360Sstevel@tonic-gate 
4370Sstevel@tonic-gate void
4382881Smp153739 usage(char *name)
4390Sstevel@tonic-gate {
4400Sstevel@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);
4414960Swillf     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"
4424960Swillf 	    "\nwhere,\n\t[-x db_args]* - any number of database specific arguments.\n"
4434960Swillf 	    "\t\t\tLook at each database documentation for supported arguments\n",
4444960Swillf 	    name);
4450Sstevel@tonic-gate     return;
4460Sstevel@tonic-gate }
4470Sstevel@tonic-gate 
4480Sstevel@tonic-gate void
4492881Smp153739 initialize_realms(krb5_context kcontext, int argc, char **argv)
4500Sstevel@tonic-gate {
4510Sstevel@tonic-gate     int 		c;
4520Sstevel@tonic-gate     char		*db_name = (char *) NULL;
4530Sstevel@tonic-gate     char		*mkey_name = (char *) NULL;
4540Sstevel@tonic-gate     char		*rcname = KDCRCACHE;
4556426Smp153739     char		*lrealm = NULL;
4560Sstevel@tonic-gate     krb5_error_code	retval;
4570Sstevel@tonic-gate     krb5_enctype	menctype = ENCTYPE_UNKNOWN;
4580Sstevel@tonic-gate     kdc_realm_t		*rdatap;
4590Sstevel@tonic-gate     krb5_boolean	manual = FALSE;
4600Sstevel@tonic-gate     char		*default_udp_ports = 0;
4610Sstevel@tonic-gate     char		*default_tcp_ports = 0;
4620Sstevel@tonic-gate     krb5_pointer	aprof;
4630Sstevel@tonic-gate     const char		*hierarchy[3];
4644960Swillf     char               **db_args      = NULL;
4654960Swillf     int                  db_args_size = 0;
4664960Swillf 
4670Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
4680Sstevel@tonic-gate     char                *v4mode = 0;
4690Sstevel@tonic-gate #endif
4700Sstevel@tonic-gate     extern char *optarg;
4710Sstevel@tonic-gate 
4720Sstevel@tonic-gate     if (!krb5_aprof_init(DEFAULT_KDC_PROFILE, KDC_PROFILE_ENV, &aprof)) {
4730Sstevel@tonic-gate 	hierarchy[0] = "kdcdefaults";
4740Sstevel@tonic-gate 	hierarchy[1] = "kdc_ports";
4750Sstevel@tonic-gate 	hierarchy[2] = (char *) NULL;
4760Sstevel@tonic-gate 	if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_udp_ports))
4770Sstevel@tonic-gate 	    default_udp_ports = 0;
4780Sstevel@tonic-gate 	hierarchy[1] = "kdc_tcp_ports";
4790Sstevel@tonic-gate 	if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_tcp_ports))
4800Sstevel@tonic-gate 	    default_tcp_ports = 0;
4810Sstevel@tonic-gate 	hierarchy[1] = "kdc_max_tcp_connections";
4820Sstevel@tonic-gate 	if (krb5_aprof_get_int32(aprof, hierarchy, TRUE,
4830Sstevel@tonic-gate 		&max_tcp_data_connections)) {
4840Sstevel@tonic-gate 	    max_tcp_data_connections = DEFAULT_KDC_TCP_CONNECTIONS;
4850Sstevel@tonic-gate 	} else if (max_tcp_data_connections < MIN_KDC_TCP_CONNECTIONS) {
4860Sstevel@tonic-gate 	    max_tcp_data_connections = DEFAULT_KDC_TCP_CONNECTIONS;
4870Sstevel@tonic-gate 	}
4880Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
4890Sstevel@tonic-gate 	hierarchy[1] = "v4_mode";
4900Sstevel@tonic-gate 	if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &v4mode))
4910Sstevel@tonic-gate 	    v4mode = 0;
4920Sstevel@tonic-gate #endif
4930Sstevel@tonic-gate 	/* aprof_init can return 0 with aprof == NULL */
4940Sstevel@tonic-gate 	if (aprof)
4950Sstevel@tonic-gate 	     krb5_aprof_finish(aprof);
4960Sstevel@tonic-gate     }
4970Sstevel@tonic-gate     if (default_udp_ports == 0)
4980Sstevel@tonic-gate 	default_udp_ports = strdup(DEFAULT_KDC_UDP_PORTLIST);
4990Sstevel@tonic-gate     if (default_tcp_ports == 0)
5000Sstevel@tonic-gate 	default_tcp_ports = strdup(DEFAULT_KDC_TCP_PORTLIST);
5010Sstevel@tonic-gate     /*
5020Sstevel@tonic-gate      * Loop through the option list.  Each time we encounter a realm name,
5030Sstevel@tonic-gate      * use the previously scanned options to fill in for defaults.
5040Sstevel@tonic-gate      */
5054960Swillf     while ((c = getopt(argc, argv, "x:r:d:mM:k:R:e:p:s:n4:X3")) != -1) {
5060Sstevel@tonic-gate 	switch(c) {
5074960Swillf 	case 'x':
5084960Swillf 	    db_args_size++;
5094960Swillf 	    {
5104960Swillf 		char **temp = realloc( db_args, sizeof(char*) * (db_args_size+1)); /* one for NULL */
5114960Swillf 		if( temp == NULL )
5124960Swillf 		{
5136426Smp153739 			/* Solaris Kerberos: Keep error messages consistent */
5146426Smp153739 		    com_err(argv[0], errno, gettext("while initializing KDC"));
5154960Swillf 		    exit(1);
5164960Swillf 		}
5174960Swillf 
5184960Swillf 		db_args = temp;
5194960Swillf 	    }
5204960Swillf 	    db_args[db_args_size-1] = optarg;
5214960Swillf 	    db_args[db_args_size]   = NULL;
5224960Swillf 	  break;
5234960Swillf 
5240Sstevel@tonic-gate 	case 'r':			/* realm name for db */
5250Sstevel@tonic-gate 	    if (!find_realm_data(optarg, (krb5_ui_4) strlen(optarg))) {
5260Sstevel@tonic-gate 		if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) {
5276426Smp153739 		    if ((retval = init_realm(kcontext, argv[0], rdatap, optarg,
5280Sstevel@tonic-gate 					     mkey_name, menctype,
5290Sstevel@tonic-gate 					     default_udp_ports,
5304960Swillf 					     default_tcp_ports, manual, db_args))) {
5316426Smp153739 			/* Solaris Kerberos: Keep error messages consistent */
5326426Smp153739 			com_err(argv[0], retval, gettext("while initializing realm %s"), optarg);
5330Sstevel@tonic-gate 			exit(1);
5340Sstevel@tonic-gate 		    }
5350Sstevel@tonic-gate 		    kdc_realmlist[kdc_numrealms] = rdatap;
5360Sstevel@tonic-gate 		    kdc_numrealms++;
5374960Swillf 		    free(db_args), db_args=NULL, db_args_size = 0;
5384960Swillf 		}
5394960Swillf 		else
5404960Swillf 		{
5416426Smp153739 			/* Solaris Kerberos: Keep error messages consistent */
5426426Smp153739 			com_err(argv[0], errno, gettext("while initializing realm %s"), optarg);
5434960Swillf 			exit(1);
5440Sstevel@tonic-gate 		}
5450Sstevel@tonic-gate 	    }
5460Sstevel@tonic-gate 	    break;
5470Sstevel@tonic-gate 	case 'd':			/* pathname for db */
5484960Swillf 	    /* now db_name is not a seperate argument. It has to be passed as part of the db_args */
5494960Swillf 	    if( db_name == NULL )
5504960Swillf 	    {
5514960Swillf 		db_name = malloc(sizeof("dbname=") + strlen(optarg));
5524960Swillf 		if( db_name == NULL )
5534960Swillf 		{
5546426Smp153739 			/* Solaris Kerberos: Keep error messages consistent */
5556426Smp153739 			com_err(argv[0], errno, gettext("while initializing KDC"));
5564960Swillf 			exit(1);
5574960Swillf 		}
5584960Swillf 
5594960Swillf 		sprintf( db_name, "dbname=%s", optarg);
5604960Swillf 	    }
5614960Swillf 
5624960Swillf 	    db_args_size++;
5634960Swillf 	    {
5644960Swillf 		char **temp = realloc( db_args, sizeof(char*) * (db_args_size+1)); /* one for NULL */
5654960Swillf 		if( temp == NULL )
5664960Swillf 		{
5676426Smp153739 			/* Solaris Kerberos: Keep error messages consistent */
5686426Smp153739 		    com_err(argv[0], errno, gettext("while initializing KDC"));
5694960Swillf 		    exit(1);
5704960Swillf 		}
5714960Swillf 
5724960Swillf 		db_args = temp;
5734960Swillf 	    }
5744960Swillf 	    db_args[db_args_size-1] = db_name;
5754960Swillf 	    db_args[db_args_size]   = NULL;
5760Sstevel@tonic-gate 	    break;
5770Sstevel@tonic-gate 	case 'm':			/* manual type-in of master key */
5780Sstevel@tonic-gate 	    manual = TRUE;
5790Sstevel@tonic-gate 	    if (menctype == ENCTYPE_UNKNOWN)
5800Sstevel@tonic-gate 		menctype = ENCTYPE_DES_CBC_CRC;
5810Sstevel@tonic-gate 	    break;
5820Sstevel@tonic-gate 	case 'M':			/* master key name in DB */
5830Sstevel@tonic-gate 	    mkey_name = optarg;
5840Sstevel@tonic-gate 	    break;
5850Sstevel@tonic-gate 	case 'n':
5860Sstevel@tonic-gate 	    nofork++;			/* don't detach from terminal */
5870Sstevel@tonic-gate 	    break;
5880Sstevel@tonic-gate 	case 'k':			/* enctype for master key */
5896426Smp153739 		/* Solaris Kerberos: Keep error messages consistent */
5906426Smp153739 	    if (retval = krb5_string_to_enctype(optarg, &menctype))
5916426Smp153739 		com_err(argv[0], retval,
5926426Smp153739 		    gettext("while converting %s to an enctype"), optarg);
5930Sstevel@tonic-gate 	    break;
5940Sstevel@tonic-gate 	case 'R':
5950Sstevel@tonic-gate 	    rcname = optarg;
5960Sstevel@tonic-gate 	    break;
5970Sstevel@tonic-gate 	case 'p':
5980Sstevel@tonic-gate 	    if (default_udp_ports)
5990Sstevel@tonic-gate 		free(default_udp_ports);
6000Sstevel@tonic-gate 	    default_udp_ports = strdup(optarg);
6010Sstevel@tonic-gate 
6020Sstevel@tonic-gate 	    if (default_tcp_ports)
6030Sstevel@tonic-gate 		free(default_tcp_ports);
6040Sstevel@tonic-gate 	    default_tcp_ports = strdup(optarg);
6050Sstevel@tonic-gate 
6060Sstevel@tonic-gate 	    break;
6070Sstevel@tonic-gate 	case '4':
6080Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
6090Sstevel@tonic-gate 	    if (v4mode)
6100Sstevel@tonic-gate 		free(v4mode);
6110Sstevel@tonic-gate 	    v4mode = strdup(optarg);
6120Sstevel@tonic-gate #endif
6130Sstevel@tonic-gate 	    break;
6142881Smp153739 	case 'X':
6152881Smp153739 #ifdef KRB5_KRB4_COMPAT
6162881Smp153739 		enable_v4_crossrealm(argv[0]);
6170Sstevel@tonic-gate #endif
6182881Smp153739 		break;
6190Sstevel@tonic-gate 	case '?':
6200Sstevel@tonic-gate 	default:
6210Sstevel@tonic-gate 	    usage(argv[0]);
6220Sstevel@tonic-gate 	    exit(1);
6230Sstevel@tonic-gate 	}
6240Sstevel@tonic-gate     }
6250Sstevel@tonic-gate 
6260Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
6270Sstevel@tonic-gate     /*
6280Sstevel@tonic-gate      * Setup the v4 mode
6290Sstevel@tonic-gate      */
6300Sstevel@tonic-gate     process_v4_mode(argv[0], v4mode);
6314960Swillf     free(v4mode);
6320Sstevel@tonic-gate #endif
6330Sstevel@tonic-gate 
6340Sstevel@tonic-gate     /*
6350Sstevel@tonic-gate      * Check to see if we processed any realms.
6360Sstevel@tonic-gate      */
6370Sstevel@tonic-gate     if (kdc_numrealms == 0) {
6380Sstevel@tonic-gate 	/* no realm specified, use default realm */
6390Sstevel@tonic-gate 	if ((retval = krb5_get_default_realm(kcontext, &lrealm))) {
6400Sstevel@tonic-gate 	    com_err(argv[0], retval,
6410Sstevel@tonic-gate 		gettext("while attempting to retrieve default realm"));
6426426Smp153739 	/* Solaris Kerberos: avoid double logging */
6436426Smp153739 #if 0
6442881Smp153739 	    fprintf (stderr, "%s: %s, %s", argv[0], error_message (retval),
6456426Smp153739 		gettext("attempting to retrieve default realm\n"));
6466426Smp153739 #endif
6470Sstevel@tonic-gate 	    exit(1);
6480Sstevel@tonic-gate 	}
6490Sstevel@tonic-gate 	if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) {
6506426Smp153739 	    if ((retval = init_realm(kcontext, argv[0], rdatap, lrealm,
6510Sstevel@tonic-gate 				     mkey_name, menctype, default_udp_ports,
6524960Swillf 				     default_tcp_ports, manual, db_args))) {
6536426Smp153739 		/* Solaris Kerberos: Keep error messages consistent */
6546426Smp153739 		com_err(argv[0], retval, gettext("while initializing realm %s"), lrealm);
6550Sstevel@tonic-gate 		exit(1);
6560Sstevel@tonic-gate 	    }
6570Sstevel@tonic-gate 	    kdc_realmlist[0] = rdatap;
6580Sstevel@tonic-gate 	    kdc_numrealms++;
659*7934SMark.Phalan@Sun.COM 	} else {
660*7934SMark.Phalan@Sun.COM     	    if (lrealm)
661*7934SMark.Phalan@Sun.COM 		free(lrealm);
6620Sstevel@tonic-gate 	}
6630Sstevel@tonic-gate     }
6640Sstevel@tonic-gate 
6650Sstevel@tonic-gate #ifdef USE_RCACHE
6660Sstevel@tonic-gate     /*
6670Sstevel@tonic-gate      * Now handle the replay cache.
6680Sstevel@tonic-gate      */
6690Sstevel@tonic-gate     if ((retval = kdc_initialize_rcache(kcontext, rcname))) {
6702881Smp153739 	com_err(argv[0], retval, gettext("while initializing KDC replay cache '%s'"),
6712881Smp153739 		rcname);
6720Sstevel@tonic-gate 	exit(1);
6730Sstevel@tonic-gate     }
6740Sstevel@tonic-gate #endif
6750Sstevel@tonic-gate 
6760Sstevel@tonic-gate     /* Ensure that this is set for our first request. */
6770Sstevel@tonic-gate     kdc_active_realm = kdc_realmlist[0];
678*7934SMark.Phalan@Sun.COM 
6790Sstevel@tonic-gate     if (default_udp_ports)
6800Sstevel@tonic-gate 	free(default_udp_ports);
6810Sstevel@tonic-gate     if (default_tcp_ports)
6820Sstevel@tonic-gate 	free(default_tcp_ports);
6834960Swillf     if (db_args)
6844960Swillf 	free(db_args);
6854960Swillf     if (db_name)
6864960Swillf 	free(db_name);
6870Sstevel@tonic-gate 
6880Sstevel@tonic-gate     return;
6890Sstevel@tonic-gate }
6900Sstevel@tonic-gate 
6910Sstevel@tonic-gate void
6922881Smp153739 finish_realms(char *prog)
6930Sstevel@tonic-gate {
6940Sstevel@tonic-gate     int i;
6950Sstevel@tonic-gate 
6960Sstevel@tonic-gate     for (i = 0; i < kdc_numrealms; i++) {
6970Sstevel@tonic-gate 	finish_realm(kdc_realmlist[i]);
6980Sstevel@tonic-gate 	kdc_realmlist[i] = 0;
6990Sstevel@tonic-gate     }
7000Sstevel@tonic-gate }
7010Sstevel@tonic-gate 
7020Sstevel@tonic-gate /*
7030Sstevel@tonic-gate  outline:
7040Sstevel@tonic-gate 
7050Sstevel@tonic-gate  process args & setup
7060Sstevel@tonic-gate 
7070Sstevel@tonic-gate  initialize database access (fetch master key, open DB)
7080Sstevel@tonic-gate 
7090Sstevel@tonic-gate  initialize network
7100Sstevel@tonic-gate 
7110Sstevel@tonic-gate  loop:
7120Sstevel@tonic-gate  	listen for packet
7130Sstevel@tonic-gate 
7140Sstevel@tonic-gate 	determine packet type, dispatch to handling routine
7150Sstevel@tonic-gate 		(AS or TGS (or V4?))
7160Sstevel@tonic-gate 
7170Sstevel@tonic-gate 	reflect response
7180Sstevel@tonic-gate 
7190Sstevel@tonic-gate 	exit on signal
7200Sstevel@tonic-gate 
7210Sstevel@tonic-gate  clean up secrets, close db
7220Sstevel@tonic-gate 
7230Sstevel@tonic-gate  shut down network
7240Sstevel@tonic-gate 
7250Sstevel@tonic-gate  exit
7260Sstevel@tonic-gate  */
7270Sstevel@tonic-gate 
7282881Smp153739 int main(int argc, char **argv)
7290Sstevel@tonic-gate {
7300Sstevel@tonic-gate     krb5_error_code	retval;
7310Sstevel@tonic-gate     krb5_context	kcontext;
7320Sstevel@tonic-gate     int errout = 0;
7330Sstevel@tonic-gate 
7346426Smp153739     krb5_boolean log_stderr_set;
7356426Smp153739 
7360Sstevel@tonic-gate     (void) setlocale(LC_ALL, "");
7370Sstevel@tonic-gate 
7380Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)		/* Should be defined by cc -D */
7390Sstevel@tonic-gate #define	TEXT_DOMAIN	"KRB5KDC_TEST"	/* Use this only if it weren't */
7400Sstevel@tonic-gate #endif
7410Sstevel@tonic-gate 
7420Sstevel@tonic-gate     (void) textdomain(TEXT_DOMAIN);
7430Sstevel@tonic-gate 
7440Sstevel@tonic-gate     if (strrchr(argv[0], '/'))
7450Sstevel@tonic-gate 	argv[0] = strrchr(argv[0], '/')+1;
7460Sstevel@tonic-gate 
7470Sstevel@tonic-gate     if (!(kdc_realmlist = (kdc_realm_t **) malloc(sizeof(kdc_realm_t *) *
7480Sstevel@tonic-gate 						  KRB5_KDC_MAX_REALMS))) {
7490Sstevel@tonic-gate 	fprintf(stderr, gettext("%s: cannot get memory for realm list\n"), argv[0]);
7500Sstevel@tonic-gate 	exit(1);
7510Sstevel@tonic-gate     }
7520Sstevel@tonic-gate     memset((char *) kdc_realmlist, 0,
7530Sstevel@tonic-gate 	   (size_t) (sizeof(kdc_realm_t *) * KRB5_KDC_MAX_REALMS));
7540Sstevel@tonic-gate 
7550Sstevel@tonic-gate     /*
7560Sstevel@tonic-gate      * A note about Kerberos contexts: This context, "kcontext", is used
7570Sstevel@tonic-gate      * for the KDC operations, i.e. setup, network connection and error
7580Sstevel@tonic-gate      * reporting.  The per-realm operations use the "realm_context"
7590Sstevel@tonic-gate      * associated with each realm.
7600Sstevel@tonic-gate      */
7614960Swillf     retval = krb5int_init_context_kdc(&kcontext);
7620Sstevel@tonic-gate     if (retval) {
7630Sstevel@tonic-gate 	    com_err(argv[0], retval, gettext("while initializing krb5"));
7640Sstevel@tonic-gate 	    exit(1);
7650Sstevel@tonic-gate     }
7660Sstevel@tonic-gate     krb5_klog_init(kcontext, "kdc", argv[0], 1);
7676426Smp153739 
7686426Smp153739     /*
7696426Smp153739      * Solaris Kerberos:
7706426Smp153739      * In the early stages of krb5kdc it is desirable to log error messages
7716426Smp153739      * to stderr as well as any other logging locations specified in config
7726426Smp153739      * files.
7736426Smp153739      */
7746426Smp153739      log_stderr_set = krb5_klog_logging_to_stderr();
7756426Smp153739      if (log_stderr_set != TRUE) {
7766426Smp153739      	krb5_klog_add_stderr();
7776426Smp153739      }
7786426Smp153739 
7790Sstevel@tonic-gate     /* initialize_kdc5_error_table();  SUNWresync121 XXX */
7800Sstevel@tonic-gate 
7810Sstevel@tonic-gate     /*
7820Sstevel@tonic-gate      * Scan through the argument list
7830Sstevel@tonic-gate      */
7840Sstevel@tonic-gate     initialize_realms(kcontext, argc, argv);
7850Sstevel@tonic-gate 
7860Sstevel@tonic-gate     setup_signal_handlers();
7870Sstevel@tonic-gate 
788*7934SMark.Phalan@Sun.COM     load_preauth_plugins(kcontext);
789*7934SMark.Phalan@Sun.COM 
7902881Smp153739     retval = setup_sam();
7912881Smp153739     if (retval) {
7920Sstevel@tonic-gate 	com_err(argv[0], retval, gettext("while initializing SAM"));
7930Sstevel@tonic-gate 	finish_realms(argv[0]);
7940Sstevel@tonic-gate 	return 1;
7950Sstevel@tonic-gate     }
7960Sstevel@tonic-gate 
7970Sstevel@tonic-gate     if ((retval = setup_network(argv[0]))) {
7980Sstevel@tonic-gate 	com_err(argv[0], retval, gettext("while initializing network"));
7990Sstevel@tonic-gate 	finish_realms(argv[0]);
8000Sstevel@tonic-gate 	return 1;
8010Sstevel@tonic-gate     }
8026426Smp153739 
8036426Smp153739     /* Solaris Kerberos: Remove the extra stderr logging */
8046426Smp153739     if (log_stderr_set != TRUE)
8056426Smp153739 	krb5_klog_remove_stderr();
8066426Smp153739 
8076426Smp153739     /*
8086426Smp153739      * Solaris Kerberos:
8096426Smp153739      * List the logs (FILE, STDERR, etc) which are currently being
8106426Smp153739      * logged to and print that to stderr. Useful when trying to
8116426Smp153739      * track down a failure via SMF.
8126426Smp153739      */
8136426Smp153739     if (retval = krb5_klog_list_logs(argv[0])) {
8146426Smp153739 	com_err(argv[0], retval, gettext("while listing logs"));
8156426Smp153739 	if (log_stderr_set != TRUE) {
8166426Smp153739 		fprintf(stderr, gettext("%s: %s while listing logs\n"),
8176426Smp153739 		    argv[0], error_message(retval));
8186426Smp153739 	}
8196426Smp153739     }
8206426Smp153739 
8210Sstevel@tonic-gate     if (!nofork && daemon(0, 0)) {
8220Sstevel@tonic-gate 	com_err(argv[0], errno, gettext("while detaching from tty"));
8236426Smp153739 	if (log_stderr_set != TRUE) {
8246426Smp153739 		fprintf(stderr, gettext("%s: %s while detaching from tty\n"),
8256426Smp153739 		  argv[0], strerror(errno));
8266426Smp153739 	}
8270Sstevel@tonic-gate 	finish_realms(argv[0]);
8280Sstevel@tonic-gate 	return 1;
8290Sstevel@tonic-gate     }
8300Sstevel@tonic-gate     if (retval = krb5_klog_syslog(LOG_INFO, "commencing operation")) {
8310Sstevel@tonic-gate 	com_err(argv[0], retval, gettext("while logging message"));
8320Sstevel@tonic-gate 	errout++;
8330Sstevel@tonic-gate 	};
8346426Smp153739 
8350Sstevel@tonic-gate     if ((retval = listen_and_process(argv[0]))) {
8360Sstevel@tonic-gate 	com_err(argv[0], retval, gettext("while processing network requests"));
8370Sstevel@tonic-gate 	errout++;
8380Sstevel@tonic-gate     }
8390Sstevel@tonic-gate     if ((retval = closedown_network(argv[0]))) {
8400Sstevel@tonic-gate 	com_err(argv[0], retval, gettext("while shutting down network"));
8410Sstevel@tonic-gate 	errout++;
8420Sstevel@tonic-gate     }
8430Sstevel@tonic-gate     krb5_klog_syslog(LOG_INFO, "shutting down");
844*7934SMark.Phalan@Sun.COM     unload_preauth_plugins(kcontext);
8450Sstevel@tonic-gate     krb5_klog_close(kdc_context);
8460Sstevel@tonic-gate     finish_realms(argv[0]);
8472881Smp153739     if (kdc_realmlist)
8482881Smp153739       free(kdc_realmlist);
8492881Smp153739 #ifdef USE_RCACHE
8502881Smp153739     (void) krb5_rc_close(kcontext, kdc_rcache);
8512881Smp153739 #endif
8522881Smp153739 #ifndef NOCACHE
8532881Smp153739     kdc_free_lookaside(kcontext);
8542881Smp153739 #endif
8550Sstevel@tonic-gate     krb5_free_context(kcontext);
8560Sstevel@tonic-gate     return errout;
8570Sstevel@tonic-gate }
8582881Smp153739 
8592881Smp153739 
8602881Smp153739 
8612881Smp153739 
862