dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / krb5 / krb5kdc / main.c
blob9687539fe5055a6d127e0539c9d22ff23e05908d
1 /*
2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
7 /*
8 * kdc/main.c
10 * Copyright 1990,2001 by the Massachusetts Institute of Technology.
12 * Export of this software from the United States of America may
13 * require a specific license from the United States Government.
14 * It is the responsibility of any person or organization contemplating
15 * export to obtain such a license before exporting.
17 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
18 * distribute this software and its documentation for any purpose and
19 * without fee is hereby granted, provided that the above copyright
20 * notice appear in all copies and that both that copyright notice and
21 * this permission notice appear in supporting documentation, and that
22 * the name of M.I.T. not be used in advertising or publicity pertaining
23 * to distribution of the software without specific, written prior
24 * permission. Furthermore if you modify this software you must label
25 * your software as modified software and not distribute it in such a
26 * fashion that it might be confused with the original M.I.T. software.
27 * M.I.T. makes no representations about the suitability of
28 * this software for any purpose. It is provided "as is" without express
29 * or implied warranty.
32 * Main procedure body for the KDC server process.
35 #include <stdio.h>
36 #include <syslog.h>
37 #include <signal.h>
38 #include <errno.h>
39 #include <netdb.h>
41 #include "k5-int.h"
42 #include "com_err.h"
43 #include "adm.h"
44 #include "adm_proto.h"
45 #include "kdc_util.h"
46 #include "extern.h"
47 #include "kdc5_err.h"
48 #include <libintl.h>
49 #include <locale.h>
51 #ifdef HAVE_NETINET_IN_H
52 #include <netinet/in.h>
53 #endif
55 #ifdef KRB5_KRB4_COMPAT
56 #include <des.h>
57 #endif
59 #if defined(NEED_DAEMON_PROTO)
60 extern int daemon(int, int);
61 #endif
63 void usage (char *);
65 krb5_sigtype request_exit (int);
66 krb5_sigtype request_hup (int);
68 void setup_signal_handlers (void);
70 krb5_error_code setup_sam (void);
72 void initialize_realms (krb5_context, int, char **);
74 void finish_realms (char *);
76 static int nofork = 0;
77 static int rkey_init_done = 0;
79 /* Solaris Kerberos: global here that other functions access */
80 int max_tcp_data_connections;
82 #ifdef POSIX_SIGNALS
83 static struct sigaction s_action;
84 #endif /* POSIX_SIGNALS */
86 #define KRB5_KDC_MAX_REALMS 32
89 * Find the realm entry for a given realm.
91 kdc_realm_t *
92 find_realm_data(char *rname, krb5_ui_4 rsize)
94 int i;
95 for (i=0; i<kdc_numrealms; i++) {
96 if ((rsize == strlen(kdc_realmlist[i]->realm_name)) &&
97 !strncmp(rname, kdc_realmlist[i]->realm_name, rsize))
98 return(kdc_realmlist[i]);
100 return((kdc_realm_t *) NULL);
103 krb5_error_code
104 setup_server_realm(krb5_principal sprinc)
106 krb5_error_code kret;
107 kdc_realm_t *newrealm;
109 kret = 0;
110 if (kdc_numrealms > 1) {
111 if (!(newrealm = find_realm_data(sprinc->realm.data,
112 (krb5_ui_4) sprinc->realm.length)))
113 kret = ENOENT;
114 else
115 kdc_active_realm = newrealm;
117 else
118 kdc_active_realm = kdc_realmlist[0];
119 return(kret);
122 static void
123 finish_realm(kdc_realm_t *rdp)
125 free(rdp->realm_dbname);
126 free(rdp->realm_mpname);
127 free(rdp->realm_stash);
128 free(rdp->realm_ports);
129 free(rdp->realm_tcp_ports);
130 if (rdp->realm_keytab)
131 krb5_kt_close(rdp->realm_context, rdp->realm_keytab);
132 if (rdp->realm_context) {
133 if (rdp->realm_mprinc)
134 krb5_free_principal(rdp->realm_context, rdp->realm_mprinc);
135 if (rdp->realm_mkey.length && rdp->realm_mkey.contents) {
136 memset(rdp->realm_mkey.contents, 0, rdp->realm_mkey.length);
137 free(rdp->realm_mkey.contents);
139 krb5_db_fini(rdp->realm_context);
140 if (rdp->realm_tgsprinc)
141 krb5_free_principal(rdp->realm_context, rdp->realm_tgsprinc);
142 krb5_free_context(rdp->realm_context);
144 memset((char *) rdp, 0, sizeof(*rdp));
145 free(rdp);
149 * Initialize a realm control structure from the alternate profile or from
150 * the specified defaults.
152 * After we're complete here, the essence of the realm is embodied in the
153 * realm data and we should be all set to begin operation for that realm.
155 static krb5_error_code
156 init_realm(krb5_context kcontext, char *progname, kdc_realm_t *rdp, char *realm,
157 char *def_mpname, krb5_enctype def_enctype, char *def_udp_ports,
158 char *def_tcp_ports, krb5_boolean def_manual, char **db_args)
160 krb5_error_code kret;
161 krb5_boolean manual;
162 krb5_realm_params *rparams;
164 memset((char *) rdp, 0, sizeof(kdc_realm_t));
165 if (!realm) {
166 kret = EINVAL;
167 goto whoops;
170 rdp->realm_name = realm;
171 kret = krb5int_init_context_kdc(&rdp->realm_context);
172 if (kret) {
173 com_err(progname, kret, gettext("while getting context for realm %s"),
174 realm);
175 goto whoops;
179 * Solaris Kerberos:
180 * Set the current context to that of the realm being init'ed
182 krb5_klog_set_context(rdp->realm_context);
184 kret = krb5_read_realm_params(rdp->realm_context, rdp->realm_name,
185 &rparams);
186 if (kret) {
187 com_err(progname, kret, gettext("while reading realm parameters"));
188 goto whoops;
191 /* Handle profile file name */
192 if (rparams && rparams->realm_profile)
193 rdp->realm_profile = strdup(rparams->realm_profile);
195 /* Handle master key name */
196 if (rparams && rparams->realm_mkey_name)
197 rdp->realm_mpname = strdup(rparams->realm_mkey_name);
198 else
199 rdp->realm_mpname = (def_mpname) ? strdup(def_mpname) :
200 strdup(KRB5_KDB_M_NAME);
202 /* Handle KDC ports */
203 if (rparams && rparams->realm_kdc_ports)
204 rdp->realm_ports = strdup(rparams->realm_kdc_ports);
205 else
206 rdp->realm_ports = strdup(def_udp_ports);
207 if (rparams && rparams->realm_kdc_tcp_ports)
208 rdp->realm_tcp_ports = strdup(rparams->realm_kdc_tcp_ports);
209 else
210 rdp->realm_tcp_ports = strdup(def_tcp_ports);
212 /* Handle stash file */
213 if (rparams && rparams->realm_stash_file) {
214 rdp->realm_stash = strdup(rparams->realm_stash_file);
215 manual = FALSE;
216 } else
217 manual = def_manual;
219 /* Handle master key type */
220 if (rparams && rparams->realm_enctype_valid)
221 rdp->realm_mkey.enctype = (krb5_enctype) rparams->realm_enctype;
222 else
223 rdp->realm_mkey.enctype = manual ? def_enctype : ENCTYPE_UNKNOWN;
225 /* Handle reject-bad-transit flag */
226 if (rparams && rparams->realm_reject_bad_transit_valid)
227 rdp->realm_reject_bad_transit = rparams->realm_reject_bad_transit;
228 else
229 rdp->realm_reject_bad_transit = 1;
231 /* Handle ticket maximum life */
232 rdp->realm_maxlife = (rparams && rparams->realm_max_life_valid) ?
233 rparams->realm_max_life : KRB5_KDB_MAX_LIFE;
235 /* Handle ticket renewable maximum life */
236 rdp->realm_maxrlife = (rparams && rparams->realm_max_rlife_valid) ?
237 rparams->realm_max_rlife : KRB5_KDB_MAX_RLIFE;
239 if (rparams)
240 krb5_free_realm_params(rdp->realm_context, rparams);
243 * We've got our parameters, now go and setup our realm context.
246 /* Set the default realm of this context */
247 if ((kret = krb5_set_default_realm(rdp->realm_context, realm))) {
248 com_err(progname, kret, gettext("while setting default realm to %s"),
249 realm);
250 goto whoops;
253 /* first open the database before doing anything */
254 #ifdef KRBCONF_KDC_MODIFIES_KDB
255 if ((kret = krb5_db_open(rdp->realm_context, db_args,
256 KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_KDC))) {
257 #else
258 if ((kret = krb5_db_open(rdp->realm_context, db_args,
259 KRB5_KDB_OPEN_RO | KRB5_KDB_SRV_TYPE_KDC))) {
260 #endif
262 * Solaris Kerberos:
263 * Make sure that error messages are printed using gettext
265 com_err(progname, kret,
266 gettext("while initializing database for realm %s"), realm);
267 goto whoops;
270 /* Assemble and parse the master key name */
271 if ((kret = krb5_db_setup_mkey_name(rdp->realm_context, rdp->realm_mpname,
272 rdp->realm_name, (char **) NULL,
273 &rdp->realm_mprinc))) {
274 com_err(progname, kret,
275 gettext("while setting up master key name %s for realm %s"),
276 rdp->realm_mpname, realm);
277 goto whoops;
281 * Get the master key.
283 if ((kret = krb5_db_fetch_mkey(rdp->realm_context, rdp->realm_mprinc,
284 rdp->realm_mkey.enctype, manual,
285 FALSE, rdp->realm_stash,
286 0, &rdp->realm_mkey))) {
287 com_err(progname, kret,
288 gettext("while fetching master key %s for realm %s"),
289 rdp->realm_mpname, realm);
290 goto whoops;
293 /* Verify the master key */
294 if ((kret = krb5_db_verify_master_key(rdp->realm_context,
295 rdp->realm_mprinc,
296 &rdp->realm_mkey))) {
297 com_err(progname, kret,
298 gettext("while verifying master key for realm %s"),
299 realm);
300 goto whoops;
303 if ((kret = krb5_db_set_mkey(rdp->realm_context, &rdp->realm_mkey))) {
304 com_err(progname, kret,
305 gettext("while processing master key for realm %s"),
306 realm);
307 goto whoops;
310 /* Set up the keytab */
311 if ((kret = krb5_ktkdb_resolve(rdp->realm_context, NULL,
312 &rdp->realm_keytab))) {
313 com_err(progname, kret,
314 gettext("while resolving kdb keytab for realm %s"),
315 realm);
316 goto whoops;
319 /* Preformat the TGS name */
320 if ((kret = krb5_build_principal(rdp->realm_context, &rdp->realm_tgsprinc,
321 strlen(realm), realm, KRB5_TGS_NAME,
322 realm, (char *) NULL))) {
323 com_err(progname, kret,
324 gettext("while building TGS name for realm %s"),
325 realm);
326 goto whoops;
329 if (!rkey_init_done) {
330 krb5_data seed;
331 #ifdef KRB5_KRB4_COMPAT
332 krb5_keyblock temp_key;
333 #endif
335 * If all that worked, then initialize the random key
336 * generators.
339 seed.length = rdp->realm_mkey.length;
340 seed.data = (char *)rdp->realm_mkey.contents;
341 /* SUNW14resync - XXX */
342 #if 0
343 if ((kret = krb5_c_random_add_entropy(rdp->realm_context,
344 KRB5_C_RANDSOURCE_TRUSTEDPARTY, &seed)))
345 goto whoops;
346 #endif
348 #ifdef KRB5_KRB4_COMPAT
349 if ((kret = krb5_c_make_random_key(rdp->realm_context,
350 ENCTYPE_DES_CBC_CRC, &temp_key))) {
351 com_err(progname, kret,
352 "while initializing V4 random key generator");
353 goto whoops;
356 (void) des_init_random_number_generator(temp_key.contents);
357 krb5_free_keyblock_contents(rdp->realm_context, &temp_key);
358 #endif
359 rkey_init_done = 1;
361 whoops:
363 * If we choked, then clean up any dirt we may have dropped on the floor.
365 if (kret) {
367 finish_realm(rdp);
371 * Solaris Kerberos:
372 * Set the current context back to the general context
374 krb5_klog_set_context(kcontext);
376 return(kret);
379 krb5_sigtype
380 request_exit(int signo)
382 signal_requests_exit = 1;
384 #ifdef POSIX_SIGTYPE
385 return;
386 #else
387 return(0);
388 #endif
391 krb5_sigtype
392 request_hup(int signo)
394 signal_requests_hup = 1;
396 #ifdef POSIX_SIGTYPE
397 return;
398 #else
399 return(0);
400 #endif
403 void
404 setup_signal_handlers(void)
406 #ifdef POSIX_SIGNALS
407 (void) sigemptyset(&s_action.sa_mask);
408 s_action.sa_flags = 0;
409 s_action.sa_handler = request_exit;
410 (void) sigaction(SIGINT, &s_action, NULL);
411 (void) sigaction(SIGTERM, &s_action, NULL);
412 s_action.sa_handler = request_hup;
413 (void) sigaction(SIGHUP, &s_action, NULL);
414 s_action.sa_handler = SIG_IGN;
415 (void) sigaction(SIGPIPE, &s_action, NULL);
416 #else /* POSIX_SIGNALS */
417 signal(SIGINT, request_exit);
418 signal(SIGTERM, request_exit);
419 signal(SIGHUP, request_hup);
420 signal(SIGPIPE, SIG_IGN);
421 #endif /* POSIX_SIGNALS */
423 return;
426 krb5_error_code
427 setup_sam(void)
429 return krb5_c_make_random_key(kdc_context, ENCTYPE_DES_CBC_MD5, &psr_key);
432 void
433 usage(char *name)
435 fprintf(stderr, gettext("usage: %s [-d dbpathname] [-r dbrealmname] [-R replaycachename ]\n\t[-m] [-k masterenctype] [-M masterkeyname] [-p port] [-n]\n"), name);
436 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"
437 "\nwhere,\n\t[-x db_args]* - any number of database specific arguments.\n"
438 "\t\t\tLook at each database documentation for supported arguments\n",
439 name);
440 return;
443 void
444 initialize_realms(krb5_context kcontext, int argc, char **argv)
446 int c;
447 char *db_name = (char *) NULL;
448 char *mkey_name = (char *) NULL;
449 char *rcname = KDCRCACHE;
450 char *lrealm = NULL;
451 krb5_error_code retval;
452 krb5_enctype menctype = ENCTYPE_UNKNOWN;
453 kdc_realm_t *rdatap;
454 krb5_boolean manual = FALSE;
455 char *default_udp_ports = 0;
456 char *default_tcp_ports = 0;
457 krb5_pointer aprof;
458 const char *hierarchy[3];
459 char **db_args = NULL;
460 int db_args_size = 0;
462 #ifdef KRB5_KRB4_COMPAT
463 char *v4mode = 0;
464 #endif
465 extern char *optarg;
467 if (!krb5_aprof_init(DEFAULT_KDC_PROFILE, KDC_PROFILE_ENV, &aprof)) {
468 hierarchy[0] = "kdcdefaults";
469 hierarchy[1] = "kdc_ports";
470 hierarchy[2] = (char *) NULL;
471 if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_udp_ports))
472 default_udp_ports = 0;
473 hierarchy[1] = "kdc_tcp_ports";
474 if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_tcp_ports))
475 default_tcp_ports = 0;
476 hierarchy[1] = "kdc_max_tcp_connections";
477 if (krb5_aprof_get_int32(aprof, hierarchy, TRUE,
478 &max_tcp_data_connections)) {
479 max_tcp_data_connections = DEFAULT_KDC_TCP_CONNECTIONS;
480 } else if (max_tcp_data_connections < MIN_KDC_TCP_CONNECTIONS) {
481 max_tcp_data_connections = DEFAULT_KDC_TCP_CONNECTIONS;
483 #ifdef KRB5_KRB4_COMPAT
484 hierarchy[1] = "v4_mode";
485 if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &v4mode))
486 v4mode = 0;
487 #endif
488 /* aprof_init can return 0 with aprof == NULL */
489 if (aprof)
490 krb5_aprof_finish(aprof);
492 if (default_udp_ports == 0)
493 default_udp_ports = strdup(DEFAULT_KDC_UDP_PORTLIST);
494 if (default_tcp_ports == 0)
495 default_tcp_ports = strdup(DEFAULT_KDC_TCP_PORTLIST);
497 * Loop through the option list. Each time we encounter a realm name,
498 * use the previously scanned options to fill in for defaults.
500 while ((c = getopt(argc, argv, "x:r:d:mM:k:R:e:p:s:n4:X3")) != -1) {
501 switch(c) {
502 case 'x':
503 db_args_size++;
505 char **temp = reallocarray(db_args, db_args_size + 1,
506 sizeof (char *)); /* one for NULL */
507 if( temp == NULL )
509 /* Solaris Kerberos: Keep error messages consistent */
510 com_err(argv[0], errno, gettext("while initializing KDC"));
511 exit(1);
514 db_args = temp;
516 db_args[db_args_size-1] = optarg;
517 db_args[db_args_size] = NULL;
518 break;
520 case 'r': /* realm name for db */
521 if (!find_realm_data(optarg, (krb5_ui_4) strlen(optarg))) {
522 if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) {
523 if ((retval = init_realm(kcontext, argv[0], rdatap, optarg,
524 mkey_name, menctype,
525 default_udp_ports,
526 default_tcp_ports, manual, db_args))) {
527 /* Solaris Kerberos: Keep error messages consistent */
528 com_err(argv[0], retval, gettext("while initializing realm %s"), optarg);
529 exit(1);
531 kdc_realmlist[kdc_numrealms] = rdatap;
532 kdc_numrealms++;
533 free(db_args), db_args=NULL, db_args_size = 0;
535 else
537 /* Solaris Kerberos: Keep error messages consistent */
538 com_err(argv[0], errno, gettext("while initializing realm %s"), optarg);
539 exit(1);
542 break;
543 case 'd': /* pathname for db */
544 /* now db_name is not a seperate argument. It has to be passed as part of the db_args */
545 if( db_name == NULL )
547 db_name = malloc(sizeof("dbname=") + strlen(optarg));
548 if( db_name == NULL )
550 /* Solaris Kerberos: Keep error messages consistent */
551 com_err(argv[0], errno, gettext("while initializing KDC"));
552 exit(1);
555 sprintf( db_name, "dbname=%s", optarg);
558 db_args_size++;
560 char **temp = reallocarray(db_args, db_args_size + 1,
561 sizeof (char *)); /* one for NULL */
562 if( temp == NULL )
564 /* Solaris Kerberos: Keep error messages consistent */
565 com_err(argv[0], errno, gettext("while initializing KDC"));
566 exit(1);
569 db_args = temp;
571 db_args[db_args_size-1] = db_name;
572 db_args[db_args_size] = NULL;
573 break;
574 case 'm': /* manual type-in of master key */
575 manual = TRUE;
576 if (menctype == ENCTYPE_UNKNOWN)
577 menctype = ENCTYPE_DES_CBC_CRC;
578 break;
579 case 'M': /* master key name in DB */
580 mkey_name = optarg;
581 break;
582 case 'n':
583 nofork++; /* don't detach from terminal */
584 break;
585 case 'k': /* enctype for master key */
586 /* Solaris Kerberos: Keep error messages consistent */
587 if (retval = krb5_string_to_enctype(optarg, &menctype))
588 com_err(argv[0], retval,
589 gettext("while converting %s to an enctype"), optarg);
590 break;
591 case 'R':
592 rcname = optarg;
593 break;
594 case 'p':
595 free(default_udp_ports);
596 default_udp_ports = strdup(optarg);
598 free(default_tcp_ports);
599 default_tcp_ports = strdup(optarg);
601 break;
602 case '4':
603 #ifdef KRB5_KRB4_COMPAT
604 free(v4mode);
605 v4mode = strdup(optarg);
606 #endif
607 break;
608 case 'X':
609 #ifdef KRB5_KRB4_COMPAT
610 enable_v4_crossrealm(argv[0]);
611 #endif
612 break;
613 case '?':
614 default:
615 usage(argv[0]);
616 exit(1);
620 #ifdef KRB5_KRB4_COMPAT
622 * Setup the v4 mode
624 process_v4_mode(argv[0], v4mode);
625 free(v4mode);
626 #endif
629 * Check to see if we processed any realms.
631 if (kdc_numrealms == 0) {
632 /* no realm specified, use default realm */
633 if ((retval = krb5_get_default_realm(kcontext, &lrealm))) {
634 com_err(argv[0], retval,
635 gettext("while attempting to retrieve default realm"));
636 /* Solaris Kerberos: avoid double logging */
637 #if 0
638 fprintf (stderr, "%s: %s, %s", argv[0], error_message (retval),
639 gettext("attempting to retrieve default realm\n"));
640 #endif
641 exit(1);
643 if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) {
644 if ((retval = init_realm(kcontext, argv[0], rdatap, lrealm,
645 mkey_name, menctype, default_udp_ports,
646 default_tcp_ports, manual, db_args))) {
647 /* Solaris Kerberos: Keep error messages consistent */
648 com_err(argv[0], retval, gettext("while initializing realm %s"), lrealm);
649 exit(1);
651 kdc_realmlist[0] = rdatap;
652 kdc_numrealms++;
653 } else {
654 free(lrealm);
658 #ifdef USE_RCACHE
660 * Now handle the replay cache.
662 if ((retval = kdc_initialize_rcache(kcontext, rcname))) {
663 com_err(argv[0], retval, gettext("while initializing KDC replay cache '%s'"),
664 rcname);
665 exit(1);
667 #endif
669 /* Ensure that this is set for our first request. */
670 kdc_active_realm = kdc_realmlist[0];
672 free(default_udp_ports);
673 free(default_tcp_ports);
674 free(db_args);
675 free(db_name);
677 return;
680 void
681 finish_realms(char *prog)
683 int i;
685 for (i = 0; i < kdc_numrealms; i++) {
686 finish_realm(kdc_realmlist[i]);
687 kdc_realmlist[i] = 0;
692 outline:
694 process args & setup
696 initialize database access (fetch master key, open DB)
698 initialize network
700 loop:
701 listen for packet
703 determine packet type, dispatch to handling routine
704 (AS or TGS (or V4?))
706 reflect response
708 exit on signal
710 clean up secrets, close db
712 shut down network
714 exit
717 int main(int argc, char **argv)
719 krb5_error_code retval;
720 krb5_context kcontext;
721 int errout = 0;
723 krb5_boolean log_stderr_set;
725 (void) setlocale(LC_ALL, "");
727 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
728 #define TEXT_DOMAIN "KRB5KDC_TEST" /* Use this only if it weren't */
729 #endif
731 (void) textdomain(TEXT_DOMAIN);
733 if (strrchr(argv[0], '/'))
734 argv[0] = strrchr(argv[0], '/')+1;
736 if (!(kdc_realmlist = (kdc_realm_t **) malloc(sizeof(kdc_realm_t *) *
737 KRB5_KDC_MAX_REALMS))) {
738 fprintf(stderr, gettext("%s: cannot get memory for realm list\n"), argv[0]);
739 exit(1);
741 memset((char *) kdc_realmlist, 0,
742 (size_t) (sizeof(kdc_realm_t *) * KRB5_KDC_MAX_REALMS));
745 * A note about Kerberos contexts: This context, "kcontext", is used
746 * for the KDC operations, i.e. setup, network connection and error
747 * reporting. The per-realm operations use the "realm_context"
748 * associated with each realm.
750 retval = krb5int_init_context_kdc(&kcontext);
751 if (retval) {
752 com_err(argv[0], retval, gettext("while initializing krb5"));
753 exit(1);
755 krb5_klog_init(kcontext, "kdc", argv[0], 1);
758 * Solaris Kerberos:
759 * In the early stages of krb5kdc it is desirable to log error messages
760 * to stderr as well as any other logging locations specified in config
761 * files.
763 log_stderr_set = krb5_klog_logging_to_stderr();
764 if (log_stderr_set != TRUE) {
765 krb5_klog_add_stderr();
768 /* initialize_kdc5_error_table(); SUNWresync121 XXX */
771 * Scan through the argument list
773 initialize_realms(kcontext, argc, argv);
775 setup_signal_handlers();
777 load_preauth_plugins(kcontext);
779 retval = setup_sam();
780 if (retval) {
781 com_err(argv[0], retval, gettext("while initializing SAM"));
782 finish_realms(argv[0]);
783 return 1;
786 if ((retval = setup_network(argv[0]))) {
787 com_err(argv[0], retval, gettext("while initializing network"));
788 finish_realms(argv[0]);
789 return 1;
792 /* Solaris Kerberos: Remove the extra stderr logging */
793 if (log_stderr_set != TRUE)
794 krb5_klog_remove_stderr();
797 * Solaris Kerberos:
798 * List the logs (FILE, STDERR, etc) which are currently being
799 * logged to and print that to stderr. Useful when trying to
800 * track down a failure via SMF.
802 if (retval = krb5_klog_list_logs(argv[0])) {
803 com_err(argv[0], retval, gettext("while listing logs"));
804 if (log_stderr_set != TRUE) {
805 fprintf(stderr, gettext("%s: %s while listing logs\n"),
806 argv[0], error_message(retval));
810 if (!nofork && daemon(0, 0)) {
811 com_err(argv[0], errno, gettext("while detaching from tty"));
812 if (log_stderr_set != TRUE) {
813 fprintf(stderr, gettext("%s: %s while detaching from tty\n"),
814 argv[0], strerror(errno));
816 finish_realms(argv[0]);
817 return 1;
819 if (retval = krb5_klog_syslog(LOG_INFO, "commencing operation")) {
820 com_err(argv[0], retval, gettext("while logging message"));
821 errout++;
824 if ((retval = listen_and_process(argv[0]))) {
825 com_err(argv[0], retval, gettext("while processing network requests"));
826 errout++;
828 if ((retval = closedown_network(argv[0]))) {
829 com_err(argv[0], retval, gettext("while shutting down network"));
830 errout++;
832 krb5_klog_syslog(LOG_INFO, "shutting down");
833 unload_preauth_plugins(kcontext);
834 krb5_klog_close(kdc_context);
835 finish_realms(argv[0]);
836 free(kdc_realmlist);
837 #ifdef USE_RCACHE
838 (void) krb5_rc_close(kcontext, kdc_rcache);
839 #endif
840 #ifndef NOCACHE
841 kdc_free_lookaside(kcontext);
842 #endif
843 krb5_free_context(kcontext);
844 return errout;