main.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
*
* Copyright 1990,2001 by the Massachusetts Institute of Technology.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
* It is the responsibility of any person or organization contemplating
* export to obtain such a license before exporting.
*
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
* permission. Furthermore if you modify this software you must label
* your software as modified software and not distribute it in such a
* fashion that it might be confused with the original M.I.T. software.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*
*
* Main procedure body for the KDC server process.
*/
#include <stdio.h>
#include <syslog.h>
#include <signal.h>
#include <errno.h>
#include <netdb.h>
#include "k5-int.h"
#include "com_err.h"
#include "adm.h"
#include "adm_proto.h"
#include "kdc_util.h"
#include "extern.h"
#include "kdc5_err.h"
#include <libintl.h>
#include <locale.h>
#ifdef HAVE_NETINET_IN_H
#endif
void setup_signal_handlers PROTOTYPE((void));
void finish_realms PROTOTYPE((char *));
static int nofork = 0;
static int rkey_init_done = 0;
/* Solaris Kerberos: global here that other functions access */
#ifdef POSIX_SIGNALS
#endif /* POSIX_SIGNALS */
#define KRB5_KDC_MAX_REALMS 32
/*
* Find the realm entry for a given realm.
*/
char *rname;
{
int i;
for (i=0; i<kdc_numrealms; i++) {
return(kdc_realmlist[i]);
}
return((kdc_realm_t *) NULL);
}
{
kret = 0;
if (kdc_numrealms > 1) {
else
}
else
return(kret);
}
static void
{
if (rdp->realm_dbname)
if (rdp->realm_mpname)
if (rdp->realm_stash)
if (rdp->realm_ports)
if (rdp->realm_tcp_ports)
if (rdp->realm_kstypes)
if (rdp->realm_keytab)
if (rdp->realm_context) {
if (rdp->realm_mprinc)
}
}
if (rdp->realm_tgsprinc)
}
}
/*
* Initialize a realm control structure from the alternate profile or from
* the specified defaults.
*
* After we're complete here, the essence of the realm is embodied in the
* realm data and we should be all set to begin operation for that realm.
*/
static krb5_error_code
char *progname;
char *realm;
char *def_dbname;
char *def_mpname;
char *def_udp_ports;
char *def_tcp_ports;
{
int num2get;
int i;
db_inited = 0;
if (!realm) {
goto whoops;
}
if (kret) {
realm);
goto whoops;
}
if (kret) {
goto whoops;
}
/* Handle profile file name */
/* Handle database name */
else
/* Handle master key name */
else
/* Handle KDC ports */
else
else
/* Handle stash file */
} else
manual = def_manual;
/* Handle master key type */
else
goto whoops;
}
/* Handle ticket maximum life */
else
/* Handle ticket renewable maximum life */
else
rparams->realm_num_keysalts = 0;
} else {
/*
*/
if ((kslist = (krb5_key_salt_tuple *)
malloc(sizeof(krb5_key_salt_tuple)))) {
nkslist = 1;
}
else {
realm);
exit(1);
}
}
if (rparams)
/*
* We've got our parameters, now go and setup our realm context.
*/
/* Set the default realm of this context */
realm);
goto whoops;
}
/* Assemble and parse the master key name */
&rdp->realm_mprinc))) {
gettext("while setting up master key name %s for realm %s"),
goto whoops;
}
/*
* Get the master key.
*/
0, &rdp->realm_mkey))) {
gettext("while fetching master key %s for realm %s"),
goto whoops;
}
/* Set and open the database. */
if (rdp->realm_dbname &&
gettext("while setting database name to %s for realm %s"),
goto whoops;
}
gettext("while initializing database "),
goto whoops;
} else
db_inited = 1;
/* Verify the master key */
&rdp->realm_mkey))) {
gettext("while verifying master key for realm %s"),
realm);
goto whoops;
}
/* Fetch the master key and get its version number */
num2get = 1;
if (!kret) {
if (num2get != 1)
else {
if (more) {
&db_entry,
num2get);
}
}
}
if (kret) {
gettext("while fetching master entry for realm %s"),
realm);
goto whoops;
}
/*
* Get the most recent master key. Search the key list in
*/
for (i=0; i<nkslist; i++) {
&db_entry,
kslist[i].ks_enctype,
-1,
-1,
&kdata)))
break;
}
if (!kdata) {
gettext("while finding master key for realm %s"),
realm);
goto whoops;
}
gettext("while processing master key for realm %s"),
realm);
goto whoops;
}
/* Set up the keytab */
NULL,
&rdp->realm_keytab))) {
gettext("while resolving kdb keytab for realm %s"),
realm);
goto whoops;
}
/* Preformat the TGS name */
gettext("while building TGS name for realm %s"),
realm);
goto whoops;
}
/* Get the TGS database entry */
num2get = 1;
&db_entry,
&num2get,
&more))) {
if (num2get != 1)
else {
if (more) {
&db_entry,
num2get);
}
}
}
if (kret) {
gettext("while fetching TGS entry for realm %s"),
realm);
goto whoops;
}
/*
* Get the most recent TGS key. Search the key list in
*/
for (i=0; i<nkslist; i++) {
&db_entry,
kslist[i].ks_enctype,
-1,
-1,
&kdata)))
break;
}
if (!kdata) {
gettext("while finding TGS key for realm %s"),
realm);
goto whoops;
}
&rdp->realm_mkey,
}
&db_entry,
num2get);
if (kret) {
gettext("while decrypting TGS key for realm %s"),
realm);
goto whoops;
}
if (!rkey_init_done) {
#ifdef KRB5_KRB4_COMPAT
#endif
/*
* If all that worked, then initialize the random key
* generators.
*/
goto whoops;
goto whoops;
goto whoops;
#ifdef KRB5_KRB4_COMPAT
ENCTYPE_DES_CBC_CRC, &temp_key))) {
"while initializing V4 random key generator");
goto whoops;
}
#endif
rkey_init_done = 1;
}
/*
* If we choked, then clean up any dirt we may have dropped on the floor.
*/
if (kret) {
}
return(kret);
}
int signo;
{
signal_requests_exit = 1;
#ifdef POSIX_SIGTYPE
return;
#else
return(0);
#endif
}
int signo;
{
signal_requests_hup = 1;
#ifdef POSIX_SIGTYPE
return;
#else
return(0);
#endif
}
void
{
#ifdef POSIX_SIGNALS
#else /* POSIX_SIGNALS */
#endif /* POSIX_SIGNALS */
return;
}
{
}
void
char *name;
{
fprintf(stderr, gettext("usage: %s [-d dbpathname] [-r dbrealmname] [-R replaycachename ]\n\t[-m] [-k masterenctype] [-M masterkeyname] [-p port] [-n]\n"), name);
return;
}
void
int argc;
char **argv;
{
int c;
char *lrealm;
char *default_udp_ports = 0;
char *default_tcp_ports = 0;
const char *hierarchy[3];
#ifdef KRB5_KRB4_COMPAT
char *v4mode = 0;
#endif
extern char *optarg;
#ifdef ATHENA_DES3_KLUDGE
extern struct krb5_keytypes krb5_enctypes_list[];
extern int krb5_enctypes_length;
#endif
hierarchy[0] = "kdcdefaults";
default_udp_ports = 0;
default_tcp_ports = 0;
} else if (max_tcp_data_connections < MIN_KDC_TCP_CONNECTIONS) {
}
#ifdef KRB5_KRB4_COMPAT
v4mode = 0;
#endif
/* aprof_init can return 0 with aprof == NULL */
if (aprof)
}
if (default_udp_ports == 0)
if (default_tcp_ports == 0)
/*
* Loop through the option list. Each time we encounter a realm name,
* use the previously scanned options to fill in for defaults.
*/
switch(c) {
case 'r': /* realm name for db */
default_tcp_ports, manual))) {
exit(1);
}
}
}
break;
case 'd': /* pathname for db */
break;
case 'm': /* manual type-in of master key */
if (menctype == ENCTYPE_UNKNOWN)
break;
case 'M': /* master key name in DB */
break;
case 'n':
nofork++; /* don't detach from terminal */
break;
case 'k': /* enctype for master key */
break;
case 'R':
break;
case 'p':
if (default_udp_ports)
if (default_tcp_ports)
break;
case '4':
#ifdef KRB5_KRB4_COMPAT
if (v4mode)
#endif
break;
case '3':
#ifdef ATHENA_DES3_KLUDGE
"internal inconsistency in enctypes_list"
" while disabling\n"
"des3-marc-hmac-sha1 enctype\n");
exit(1);
}
break;
#endif
case '?':
default:
exit(1);
}
}
#ifdef KRB5_KRB4_COMPAT
/*
* Setup the v4 mode
*/
#endif
/*
* Check to see if we processed any realms.
*/
if (kdc_numrealms == 0) {
/* no realm specified, use default realm */
gettext("while attempting to retrieve default realm"));
exit(1);
}
default_tcp_ports, manual))) {
gettext("%s: cannot initialize realm %s\n"),
exit(1);
}
kdc_realmlist[0] = rdatap;
}
}
#ifdef USE_RCACHE
/*
* Now handle the replay cache.
*/
exit(1);
}
#endif
/* Ensure that this is set for our first request. */
if (default_udp_ports)
if (default_tcp_ports)
return;
}
void
char *prog;
{
int i;
for (i = 0; i < kdc_numrealms; i++) {
kdc_realmlist[i] = 0;
}
}
/*
outline:
process args & setup
initialize database access (fetch master key, open DB)
initialize network
loop:
listen for packet
determine packet type, dispatch to handling routine
(AS or TGS (or V4?))
reflect response
exit on signal
clean up secrets, close db
shut down network
exit
*/
int argc;
char *argv[];
{
int *port_list;
int errout = 0;
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
#endif
(void) textdomain(TEXT_DOMAIN);
KRB5_KDC_MAX_REALMS))) {
exit(1);
}
memset((char *) kdc_realmlist, 0,
/*
* A note about Kerberos contexts: This context, "kcontext", is used
* for the KDC operations, i.e. setup, network connection and error
* reporting. The per-realm operations use the "realm_context"
* associated with each realm.
*/
if (retval) {
exit(1);
}
/* initialize_kdc5_error_table(); SUNWresync121 XXX */
/*
* Scan through the argument list
*/
finish_realms(argv[0]);
return 1;
}
finish_realms(argv[0]);
return 1;
}
finish_realms(argv[0]);
return 1;
}
errout++;
};
errout++;
}
errout++;
}
finish_realms(argv[0]);
return errout;
}