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