diff --git a/kdc/524.c b/kdc/524.c index 8fd3c2418..ca86e768d 100644 --- a/kdc/524.c +++ b/kdc/524.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2003 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -43,7 +43,9 @@ RCSID("$Id$"); */ static krb5_error_code -fetch_server (const Ticket *t, +fetch_server (krb5_context context, + struct krb5_kdc_configuration *config, + const Ticket *t, char **spn, hdb_entry **server, const char *from) @@ -53,20 +55,21 @@ fetch_server (const Ticket *t, ret = _krb5_principalname2krb5_principal(&sprinc, t->sname, t->realm); if (ret) { - kdc_log(0, "_krb5_principalname2krb5_principal: %s", + kdc_log(context, config, 0, "_krb5_principalname2krb5_principal: %s", krb5_get_err_text(context, ret)); return ret; } ret = krb5_unparse_name(context, sprinc, spn); if (ret) { krb5_free_principal(context, sprinc); - kdc_log(0, "krb5_unparse_name: %s", krb5_get_err_text(context, ret)); + kdc_log(context, config, 0, "krb5_unparse_name: %s", + krb5_get_err_text(context, ret)); return ret; } - ret = db_fetch(sprinc, server); + ret = db_fetch(context, config, sprinc, server); krb5_free_principal(context, sprinc); if (ret) { - kdc_log(0, + kdc_log(context, config, 0, "Request to convert ticket from %s for unknown principal %s: %s", from, *spn, krb5_get_err_text(context, ret)); if (ret == HDB_ERR_NOENTRY) @@ -77,7 +80,9 @@ fetch_server (const Ticket *t, } static krb5_error_code -log_524 (const EncTicketPart *et, +log_524 (krb5_context context, + struct krb5_kdc_configuration *config, + const EncTicketPart *et, const char *from, const char *spn) { @@ -87,33 +92,35 @@ log_524 (const EncTicketPart *et, ret = _krb5_principalname2krb5_principal(&client, et->cname, et->crealm); if (ret) { - kdc_log(0, "_krb5_principalname2krb5_principal: %s", + kdc_log(context, config, 0, "_krb5_principalname2krb5_principal: %s", krb5_get_err_text (context, ret)); return ret; } ret = krb5_unparse_name(context, client, &cpn); if (ret) { krb5_free_principal(context, client); - kdc_log(0, "krb5_unparse_name: %s", + kdc_log(context, config, 0, "krb5_unparse_name: %s", krb5_get_err_text (context, ret)); return ret; } - kdc_log(1, "524-REQ %s from %s for %s", cpn, from, spn); + kdc_log(context, config, 1, "524-REQ %s from %s for %s", cpn, from, spn); free(cpn); krb5_free_principal(context, client); return 0; } static krb5_error_code -verify_flags (const EncTicketPart *et, +verify_flags (krb5_context context, + struct krb5_kdc_configuration *config, + const EncTicketPart *et, const char *spn) { if(et->endtime < kdc_time){ - kdc_log(0, "Ticket expired (%s)", spn); + kdc_log(context, config, 0, "Ticket expired (%s)", spn); return KRB5KRB_AP_ERR_TKT_EXPIRED; } if(et->flags.invalid){ - kdc_log(0, "Ticket not valid (%s)", spn); + kdc_log(context, config, 0, "Ticket not valid (%s)", spn); return KRB5KRB_AP_ERR_TKT_NYV; } return 0; @@ -125,7 +132,9 @@ verify_flags (const EncTicketPart *et, */ static krb5_error_code -set_address (EncTicketPart *et, +set_address (krb5_context context, + struct krb5_kdc_configuration *config, + EncTicketPart *et, struct sockaddr *addr, const char *from) { @@ -139,12 +148,12 @@ set_address (EncTicketPart *et, ret = krb5_sockaddr2address(context, addr, v4_addr); if(ret) { free (v4_addr); - kdc_log(0, "Failed to convert address (%s)", from); + kdc_log(context, config, 0, "Failed to convert address (%s)", from); return ret; } if (et->caddr && !krb5_address_search (context, v4_addr, et->caddr)) { - kdc_log(0, "Incorrect network address (%s)", from); + kdc_log(context, config, 0, "Incorrect network address (%s)", from); krb5_free_address(context, v4_addr); free (v4_addr); return KRB5KRB_AP_ERR_BADADDR; @@ -175,7 +184,9 @@ set_address (EncTicketPart *et, static krb5_error_code -encrypt_v4_ticket(void *buf, +encrypt_v4_ticket(krb5_context context, + struct krb5_kdc_configuration *config, + void *buf, size_t len, krb5_keyblock *skey, EncryptedData *reply) @@ -185,7 +196,7 @@ encrypt_v4_ticket(void *buf, ret = krb5_crypto_init(context, skey, ETYPE_DES_PCBC_NONE, &crypto); if (ret) { free(buf); - kdc_log(0, "krb5_crypto_init failed: %s", + kdc_log(context, config, 0, "krb5_crypto_init failed: %s", krb5_get_err_text(context, ret)); return ret; } @@ -199,7 +210,7 @@ encrypt_v4_ticket(void *buf, reply); krb5_crypto_destroy(context, crypto); if(ret) { - kdc_log(0, "Failed to encrypt data: %s", + kdc_log(context, config, 0, "Failed to encrypt data: %s", krb5_get_err_text(context, ret)); return ret; } @@ -207,7 +218,9 @@ encrypt_v4_ticket(void *buf, } static krb5_error_code -encode_524_response(const char *spn, const EncTicketPart et, const Ticket *t, +encode_524_response(krb5_context context, + struct krb5_kdc_configuration *config, + const char *spn, const EncTicketPart et, const Ticket *t, hdb_entry *server, EncryptedData *ticket, int *kvno) { krb5_error_code ret; @@ -221,7 +234,8 @@ encode_524_response(const char *spn, const EncTicketPart et, const Ticket *t, &t->enc_part, &len, ret); if (ret) { - kdc_log(0, "Failed to encode v4 (2b) ticket (%s)", spn); + kdc_log(context, config, 0, + "Failed to encode v4 (2b) ticket (%s)", spn); return ret; } @@ -232,27 +246,31 @@ encode_524_response(const char *spn, const EncTicketPart et, const Ticket *t, unsigned char buf[MAX_KTXT_LEN + 4 * 4]; Key *skey; - if (!enable_v4_cross_realm && strcmp (et.crealm, t->realm) != 0) { - kdc_log(0, "524 cross-realm %s -> %s disabled", et.crealm, + if (!config->enable_v4_cross_realm && strcmp (et.crealm, t->realm) != 0) { + kdc_log(context, config, 0, "524 cross-realm %s -> %s disabled", et.crealm, t->realm); return KRB5KDC_ERR_POLICY; } - ret = encode_v4_ticket(buf + sizeof(buf) - 1, sizeof(buf), + ret = encode_v4_ticket(context, config, + buf + sizeof(buf) - 1, sizeof(buf), &et, &t->sname, &len); if(ret){ - kdc_log(0, "Failed to encode v4 ticket (%s)", spn); + kdc_log(context, config, 0, + "Failed to encode v4 ticket (%s)", spn); return ret; } - ret = get_des_key(server, TRUE, FALSE, &skey); + ret = get_des_key(context, server, TRUE, FALSE, &skey); if(ret){ - kdc_log(0, "no suitable DES key for server (%s)", spn); + kdc_log(context, config, 0, + "no suitable DES key for server (%s)", spn); return ret; } - ret = encrypt_v4_ticket(buf + sizeof(buf) - len, len, + ret = encrypt_v4_ticket(context, config, buf + sizeof(buf) - len, len, &skey->key, ticket); if(ret){ - kdc_log(0, "Failed to encrypt v4 ticket (%s)", spn); + kdc_log(context, config, 0, + "Failed to encrypt v4 ticket (%s)", spn); return ret; } *kvno = server->kvno; @@ -267,7 +285,9 @@ encode_524_response(const char *spn, const EncTicketPart et, const Ticket *t, */ krb5_error_code -do_524(const Ticket *t, krb5_data *reply, +do_524(krb5_context context, + struct krb5_kdc_configuration *config, + const Ticket *t, krb5_data *reply, const char *from, struct sockaddr *addr) { krb5_error_code ret = 0; @@ -283,25 +303,27 @@ do_524(const Ticket *t, krb5_data *reply, size_t len; int kvno = 0; - if(!enable_524) { + if(!config->enable_524) { ret = KRB5KDC_ERR_POLICY; - kdc_log(0, "Rejected ticket conversion request from %s", from); + kdc_log(context, config, 0, + "Rejected ticket conversion request from %s", from); goto out; } - ret = fetch_server (t, &spn, &server, from); + ret = fetch_server (context, config, t, &spn, &server, from); if (ret) { goto out; } ret = hdb_enctype2key(context, server, t->enc_part.etype, &skey); if(ret){ - kdc_log(0, "No suitable key found for server (%s) from %s", spn, from); + kdc_log(context, config, 0, + "No suitable key found for server (%s) from %s", spn, from); goto out; } ret = krb5_crypto_init(context, &skey->key, 0, &crypto); if (ret) { - kdc_log(0, "krb5_crypto_init failed: %s", + kdc_log(context, config, 0, "krb5_crypto_init failed: %s", krb5_get_err_text(context, ret)); goto out; } @@ -312,36 +334,39 @@ do_524(const Ticket *t, krb5_data *reply, &et_data); krb5_crypto_destroy(context, crypto); if(ret){ - kdc_log(0, "Failed to decrypt ticket from %s for %s", from, spn); + kdc_log(context, config, 0, + "Failed to decrypt ticket from %s for %s", from, spn); goto out; } ret = krb5_decode_EncTicketPart(context, et_data.data, et_data.length, &et, &len); krb5_data_free(&et_data); if(ret){ - kdc_log(0, "Failed to decode ticket from %s for %s", from, spn); + kdc_log(context, config, 0, + "Failed to decode ticket from %s for %s", from, spn); goto out; } - ret = log_524 (&et, from, spn); + ret = log_524 (context, config, &et, from, spn); if (ret) { free_EncTicketPart(&et); goto out; } - ret = verify_flags (&et, spn); + ret = verify_flags (context, config, &et, spn); if (ret) { free_EncTicketPart(&et); goto out; } - ret = set_address (&et, addr, from); + ret = set_address (context, config, &et, addr, from); if (ret) { free_EncTicketPart(&et); goto out; } - ret = encode_524_response(spn, et, t, server, &ticket, &kvno); + ret = encode_524_response(context, config, spn, et, t, + server, &ticket, &kvno); free_EncTicketPart(&et); out: @@ -364,6 +389,6 @@ out: if(spn) free(spn); if(server) - free_ent (server); + free_ent (context, server); return ret; } diff --git a/kdc/Makefile.am b/kdc/Makefile.am index 092e4695b..e4061e8c3 100644 --- a/kdc/Makefile.am +++ b/kdc/Makefile.am @@ -4,6 +4,8 @@ include $(top_srcdir)/Makefile.am.common AM_CPPFLAGS += $(INCLUDE_krb4) $(INCLUDE_des) -I$(srcdir)/../lib/krb5 +lib_LTLIBRARIES = libkdc.la + bin_PROGRAMS = string2key sbin_PROGRAMS = kstash @@ -19,20 +21,24 @@ kstash_SOURCES = kstash.c headers.h string2key_SOURCES = string2key.c headers.h -kdc_SOURCES = \ +kdc_SOURCES = connect.c \ config.c \ - connect.c \ + main.c + +libkdc_la_SOURCES = \ + default_config.c \ kdc_locl.h \ kerberos5.c \ pkinit.c \ log.c \ - main.c \ misc.c \ 524.c \ kerberos4.c \ kaserver.c \ + process.c \ rx.h +libkdc_la_LDFLAGS = -version-info 1:0:0 -Wl,--version-script,./exports hprop_LDADD = \ $(top_builddir)/lib/hdb/libhdb.la \ @@ -54,6 +60,16 @@ hpropd_LDADD = \ $(LIB_roken) \ $(DBLIB) +libkdc_la_LIBADD = \ + $(top_builddir)/lib/hdb/libhdb.la \ + $(LIB_openldap) \ + $(top_builddir)/lib/krb5/libkrb5.la \ + $(LIB_kdb) $(LIB_krb4) \ + $(LIB_des) \ + $(top_builddir)/lib/asn1/libasn1.la \ + $(LIB_roken) \ + $(DBLIB) + LDADD = $(top_builddir)/lib/hdb/libhdb.la \ $(LIB_openldap) \ $(top_builddir)/lib/krb5/libkrb5.la \ @@ -63,5 +79,6 @@ LDADD = $(top_builddir)/lib/hdb/libhdb.la \ $(LIB_roken) \ $(DBLIB) -kdc_LDADD = $(LDADD) $(LIB_pidfile) +kdc_LDADD = libkdc.la $(LIB_pidfile) +include_HEADERS = kdc.h diff --git a/kdc/config.c b/kdc/config.c index 4fa74bb2e..9bfe3c21e 100644 --- a/kdc/config.c +++ b/kdc/config.c @@ -1,6 +1,7 @@ /* - * Copyright (c) 1997-2004 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2005 Kungliga Tekniska Höskolan * (Royal Institute of Technology, Stockholm, Sweden). + * * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,50 +38,34 @@ RCSID("$Id$"); +struct dbinfo { + char *realm; + char *dbname; + char *mkey_file; + struct dbinfo *next; +}; + static const char *config_file; /* location of kdc config file */ -int require_preauth = -1; /* 1 == require preauth for all principals */ - -size_t max_request; /* maximal size of a request */ - +static int require_preauth = -1; /* 1 == require preauth for all principals */ static char *max_request_str; /* `max_request' as a string */ -time_t kdc_warn_pwexpire; /* time before expiration to print a warning */ - -struct dbinfo *databases; -HDB **db; -int num_db; - -const char *port_str; - -int detach_from_console = -1; -#define DETACH_IS_DEFAULT FALSE - -int enable_http = -1; -krb5_boolean encode_as_rep_as_tgs_rep; /* bug compatibility */ - -krb5_boolean check_ticket_addresses; -krb5_boolean allow_null_ticket_addresses; -krb5_boolean allow_anonymous; -int trpolicy; static const char *trpolicy_str; -static struct getarg_strings addresses_str; /* addresses to listen on */ -krb5_addresses explicit_addresses; - static int disable_des = -1; - -char *v4_realm; -int enable_v4 = -1; -int enable_kaserver = -1; - -int enable_524 = -1; -int enable_v4_cross_realm = -1; +static int enable_v4 = -1; +static int enable_kaserver = -1; +static int enable_524 = -1; +static int enable_v4_cross_realm = -1; static int builtin_hdb_flag; static int help_flag; static int version_flag; +static struct getarg_strings addresses_str; /* addresses to listen on */ + +static char *v4_realm; + static struct getargs args[] = { { "config-file", 'c', arg_string, &config_file, @@ -94,12 +79,6 @@ static struct getargs args[] = { "max-request", 0, arg_string, &max_request, "max size for a kdc-request", "size" }, -#if 0 - { - "database", 'd', arg_string, &databases, - "location of database", "database" - }, -#endif { "enable-http", 'H', arg_flag, &enable_http, "turn on HTTP support" }, { "524", 0, arg_negative_flag, &enable_524, "don't respond to 524 requests" @@ -153,7 +132,7 @@ usage(int ret) } static void -get_dbinfo(void) +get_dbinfo(krb5_context context, struct krb5_kdc_configuration *config) { const krb5_config_binding *top_binding = NULL; const krb5_config_binding *db_binding; @@ -162,8 +141,10 @@ get_dbinfo(void) const char *default_dbname = HDB_DEFAULT_DB; const char *default_mkey = HDB_DB_DIR "/m-key"; const char *p; + krb5_error_code ret; + + struct dbinfo *databases = NULL; - databases = NULL; dt = &databases; while((db_binding = (const krb5_config_binding *) krb5_config_get_next(context, NULL, &top_binding, @@ -229,10 +210,36 @@ get_dbinfo(void) (int)(p - di->dbname), di->dbname); } } + + if (databases == NULL) { + config->db = malloc(sizeof(*config->db)); + config->num_db = 1; + ret = hdb_create(context, &config->db[0], NULL); + if(ret) + krb5_err(context, 1, ret, "hdb_create %s", HDB_DEFAULT_DB); + ret = hdb_set_master_keyfile(context, config->db[0], NULL); + if (ret) + krb5_err(context, 1, ret, "hdb_set_master_keyfile"); + } else { + struct dbinfo *d; + int i; + /* count databases */ + for(d = databases, i = 0; d; d = d->next, i++); + config->db = malloc(i * sizeof(*config->db)); + for(d = databases, config->num_db = 0; d; d = d->next, config->num_db++) { + ret = hdb_create(context, &config->db[config->num_db], d->dbname); + if(ret) + krb5_err(context, 1, ret, "hdb_create %s", d->dbname); + ret = hdb_set_master_keyfile(context, config->db[config->num_db], d->mkey_file); + if (ret) + krb5_err(context, 1, ret, "hdb_set_master_keyfile"); + } + } + } static void -add_one_address (const char *str, int first) +add_one_address (krb5_context context, const char *str, int first) { krb5_error_code ret; krb5_addresses tmp; @@ -247,15 +254,21 @@ add_one_address (const char *str, int first) krb5_free_addresses (context, &tmp); } -void -configure(int argc, char **argv) +struct krb5_kdc_configuration *configure(krb5_context context, int argc, char **argv) { + struct krb5_kdc_configuration *config = malloc(sizeof(*config)); krb5_error_code ret; - int optind = 0; + int optidx = 0; const char *p; - while(getarg(args, num_args, argc, argv, &optind)) - warnx("error at argument `%s'", argv[optind]); + if (!config) { + return NULL; + } + + krb5_kdc_default_config(config); + + while(getarg(args, num_args, argc, argv, &optidx)) + warnx("error at argument `%s'", argv[optidx]); if(help_flag) usage (0); @@ -275,8 +288,8 @@ configure(int argc, char **argv) exit(0); } - argc -= optind; - argv += optind; + argc -= optidx; + argv += optidx; if (argc != 0) usage(1); @@ -297,7 +310,9 @@ configure(int argc, char **argv) krb5_err(context, 1, ret, "reading configuration files"); } - get_dbinfo(); + kdc_openlog(context, config); + + get_dbinfo(context, config); if(max_request_str) max_request = parse_bytes(max_request_str, NULL); @@ -312,9 +327,14 @@ configure(int argc, char **argv) max_request = parse_bytes(p, NULL); } - if(require_preauth == -1) - require_preauth = krb5_config_get_bool(context, NULL, "kdc", - "require-preauth", NULL); + if(require_preauth == -1) { + config->require_preauth = krb5_config_get_bool_default(context, NULL, + config->require_preauth, + "kdc", + "require-preauth", NULL); + } else { + config->require_preauth = require_preauth; + } if(port_str == NULL){ p = krb5_config_get_string(context, NULL, "kdc", "ports", NULL); @@ -328,58 +348,85 @@ configure(int argc, char **argv) int i; for (i = 0; i < addresses_str.num_strings; ++i) - add_one_address (addresses_str.strings[i], i == 0); + add_one_address (context, addresses_str.strings[i], i == 0); free_getarg_strings (&addresses_str); } else { char **foo = krb5_config_get_strings (context, NULL, "kdc", "addresses", NULL); if (foo != NULL) { - add_one_address (*foo++, TRUE); + add_one_address (context, *foo++, TRUE); while (*foo) - add_one_address (*foo++, FALSE); + add_one_address (context, *foo++, FALSE); } } - if(enable_v4 == -1) - enable_v4 = krb5_config_get_bool_default(context, NULL, FALSE, "kdc", - "enable-kerberos4", NULL); - if(enable_v4_cross_realm == -1) - enable_v4_cross_realm = + if(enable_v4 == -1) { + config->enable_v4 = krb5_config_get_bool_default(context, NULL, + config->enable_v4, + "kdc", + "enable-kerberos4", + NULL); + } else { + config->enable_v4 = enable_v4; + } + + if(enable_v4_cross_realm == -1) { + config->enable_v4_cross_realm = krb5_config_get_bool_default(context, NULL, - FALSE, "kdc", + config->enable_v4_cross_realm, + "kdc", "enable-kerberos4-cross-realm", NULL); - if(enable_524 == -1) - enable_524 = krb5_config_get_bool_default(context, NULL, enable_v4, - "kdc", "enable-524", NULL); + } else { + config->enable_v4_cross_realm = enable_v4_cross_realm; + } + + if(enable_524 == -1) { + config->enable_524 = krb5_config_get_bool_default(context, NULL, + config->enable_v4, + "kdc", "enable-524", + NULL); + } else { + config->enable_524 = enable_524; + } if(enable_http == -1) enable_http = krb5_config_get_bool(context, NULL, "kdc", "enable-http", NULL); - check_ticket_addresses = - krb5_config_get_bool_default(context, NULL, TRUE, "kdc", + + config->check_ticket_addresses = + krb5_config_get_bool_default(context, NULL, + config->check_ticket_addresses, + "kdc", "check-ticket-addresses", NULL); - allow_null_ticket_addresses = - krb5_config_get_bool_default(context, NULL, TRUE, "kdc", + config->allow_null_ticket_addresses = + krb5_config_get_bool_default(context, NULL, + config->allow_null_ticket_addresses, + "kdc", "allow-null-ticket-addresses", NULL); - allow_anonymous = - krb5_config_get_bool(context, NULL, "kdc", - "allow-anonymous", NULL); + config->allow_anonymous = + krb5_config_get_bool_default(context, NULL, + config->allow_anonymous, + "kdc", + "allow-anonymous", NULL); + trpolicy_str = - krb5_config_get_string_default(context, NULL, "always-check", "kdc", + krb5_config_get_string_default(context, NULL, "DEFAULT", "kdc", "transited-policy", NULL); - if(strcasecmp(trpolicy_str, "always-check") == 0) - trpolicy = TRPOLICY_ALWAYS_CHECK; - else if(strcasecmp(trpolicy_str, "allow-per-principal") == 0) - trpolicy = TRPOLICY_ALLOW_PER_PRINCIPAL; - else if(strcasecmp(trpolicy_str, "always-honour-request") == 0) - trpolicy = TRPOLICY_ALWAYS_HONOUR_REQUEST; - else { - kdc_log(0, "unknown transited-policy: %s, reverting to always-check", + if(strcasecmp(trpolicy_str, "always-check") == 0) { + config->trpolicy = TRPOLICY_ALWAYS_CHECK; + } else if(strcasecmp(trpolicy_str, "allow-per-principal") == 0) { + config->trpolicy = TRPOLICY_ALLOW_PER_PRINCIPAL; + } else if(strcasecmp(trpolicy_str, "always-honour-request") == 0) { + config->trpolicy = TRPOLICY_ALWAYS_HONOUR_REQUEST; + } else if(strcasecmp(trpolicy_str, "DEFAULT") == 0) { + /* default */ + } else { + kdc_log(context, config, + 0, "unknown transited-policy: %s, reverting to default (always-check)", trpolicy_str); - trpolicy = TRPOLICY_ALWAYS_CHECK; } if (krb5_config_get_string(context, NULL, "kdc", @@ -393,51 +440,72 @@ configure(int argc, char **argv) "v4-realm", NULL); if(p != NULL) { - v4_realm = strdup(p); - if (v4_realm == NULL) + config->v4_realm = strdup(p); + if (config->v4_realm == NULL) krb5_errx(context, 1, "out of memory"); + } else { + config->v4_realm = NULL; } + } else { + config->v4_realm = v4_realm; } - if (enable_kaserver == -1) - enable_kaserver = krb5_config_get_bool_default(context, NULL, FALSE, - "kdc", - "enable-kaserver", - NULL); - encode_as_rep_as_tgs_rep = krb5_config_get_bool(context, NULL, "kdc", - "encode_as_rep_as_tgs_rep", - NULL); + if (enable_kaserver == -1) { + config->enable_kaserver = + krb5_config_get_bool_default(context, + NULL, + config->enable_kaserver, + "kdc", + "enable-kaserver", + NULL); + } else { + config->enable_kaserver = enable_kaserver; + } - kdc_warn_pwexpire = krb5_config_get_time (context, NULL, - "kdc", - "kdc_warn_pwexpire", - NULL); + config->encode_as_rep_as_tgs_rep = + krb5_config_get_bool_default(context, NULL, + config->encode_as_rep_as_tgs_rep, + "kdc", + "encode_as_rep_as_tgs_rep", + NULL); + + config->kdc_warn_pwexpire = + krb5_config_get_time_default (context, NULL, + config->kdc_warn_pwexpire, + "kdc", + "kdc_warn_pwexpire", + NULL); if(detach_from_console == -1) detach_from_console = krb5_config_get_bool_default(context, NULL, DETACH_IS_DEFAULT, "kdc", "detach", NULL); - kdc_openlog(); + if(max_request == 0) max_request = 64 * 1024; - if(require_preauth == -1) - require_preauth = 1; + + if(require_preauth != -1) { + config->require_preauth = require_preauth; + } if (port_str == NULL) port_str = "+"; #ifdef PKINIT - enable_pkinit = krb5_config_get_bool_default(context, NULL, FALSE, - "kdc", - "enable-pkinit", - NULL); - if (enable_pkinit) { + config->enable_pkinit = + krb5_config_get_bool_default(context, + NULL, + config->enable_pkinit, + "kdc", + "enable-pkinit", + NULL); + if (config->enable_pkinit) { const char *user_id, *x509_anchors; user_id = krb5_config_get_string(context, NULL, - "kdc", - "pki-identity", - NULL); + "kdc", + "pki-identity", + NULL); if (user_id == NULL) krb5_errx(context, 1, "pkinit enabled but no identity"); @@ -450,28 +518,29 @@ configure(int argc, char **argv) pk_initialize(user_id, x509_anchors); - enable_pkinit_princ_in_cert = + config->enable_pkinit_princ_in_cert = krb5_config_get_bool_default(context, - NULL, TRUE, + NULL, + config->enable_pkinit_princ_in_cert, "kdc", "pkinit-principal-in-certificate", NULL); } #endif - if(v4_realm == NULL && (enable_kaserver || enable_v4)){ + if(config->v4_realm == NULL && (config->enable_kaserver || config->enable_v4)){ #ifdef KRB4 - v4_realm = malloc(40); /* REALM_SZ */ - if (v4_realm == NULL) + config->v4_realm = malloc(40); /* REALM_SZ */ + if (config->v4_realm == NULL) krb5_errx(context, 1, "out of memory"); - krb_get_lrealm(v4_realm, 1); + krb_get_lrealm(config->v4_realm, 1); #else krb5_errx(context, 1, "No Kerberos 4 realm configured"); #endif } if(disable_des == -1) disable_des = krb5_config_get_bool_default(context, NULL, - 0, + FALSE, "kdc", "disable-des", NULL); if(disable_des) { @@ -482,10 +551,12 @@ configure(int argc, char **argv) krb5_enctype_disable(context, ETYPE_DES_CFB64_NONE); krb5_enctype_disable(context, ETYPE_DES_PCBC_NONE); - kdc_log(0, "DES was disabled, turned off Kerberos V4, 524 " + kdc_log(context, config, + 0, "DES was disabled, turned off Kerberos V4, 524 " "and kaserver"); - enable_v4 = 0; - enable_524 = 0; - enable_kaserver = 0; + config->enable_v4 = 0; + config->enable_524 = 0; + config->enable_kaserver = 0; } + return config; } diff --git a/kdc/connect.c b/kdc/connect.c index 79e1c16a6..618e4fafa 100644 --- a/kdc/connect.c +++ b/kdc/connect.c @@ -35,6 +35,16 @@ RCSID("$Id$"); +/* Should we enable the HTTP hack? */ +int enable_http = -1; + +/* A string describing on what ports to listen */ +const char *port_str; + +krb5_addresses explicit_addresses; + +size_t max_request; /* maximal size of a request */ + /* * a tuple describing on what to listen */ @@ -55,7 +65,8 @@ static int num_ports; */ static void -add_port(int family, int port, const char *protocol) +add_port(krb5_context context, + int family, int port, const char *protocol) { int type; int i; @@ -87,11 +98,12 @@ add_port(int family, int port, const char *protocol) */ static void -add_port_service(int family, const char *service, int port, +add_port_service(krb5_context context, + int family, const char *service, int port, const char *protocol) { port = krb5_getportbyname (context, service, protocol, port); - add_port (family, port, protocol); + add_port (context, family, port, protocol); } /* @@ -100,22 +112,23 @@ add_port_service(int family, const char *service, int port, */ static void -add_port_string (int family, const char *port_str, const char *protocol) +add_port_string (krb5_context context, + int family, const char *str, const char *protocol) { struct servent *sp; int port; - sp = roken_getservbyname (port_str, protocol); + sp = roken_getservbyname (str, protocol); if (sp != NULL) { port = sp->s_port; } else { char *end; - port = htons(strtol(port_str, &end, 0)); - if (end == port_str) + port = htons(strtol(str, &end, 0)); + if (end == str) return; } - add_port (family, port, protocol); + add_port (context, family, port, protocol); } /* @@ -123,24 +136,26 @@ add_port_string (int family, const char *port_str, const char *protocol) */ static void -add_standard_ports (int family) +add_standard_ports (krb5_context context, + struct krb5_kdc_configuration *config, + int family) { - add_port_service(family, "kerberos", 88, "udp"); - add_port_service(family, "kerberos", 88, "tcp"); - add_port_service(family, "kerberos-sec", 88, "udp"); - add_port_service(family, "kerberos-sec", 88, "tcp"); + add_port_service(context, family, "kerberos", 88, "udp"); + add_port_service(context, family, "kerberos", 88, "tcp"); + add_port_service(context, family, "kerberos-sec", 88, "udp"); + add_port_service(context, family, "kerberos-sec", 88, "tcp"); if(enable_http) - add_port_service(family, "http", 80, "tcp"); - if(enable_524) { - add_port_service(family, "krb524", 4444, "udp"); - add_port_service(family, "krb524", 4444, "tcp"); + add_port_service(context, family, "http", 80, "tcp"); + if(config->enable_524) { + add_port_service(context, family, "krb524", 4444, "udp"); + add_port_service(context, family, "krb524", 4444, "tcp"); } - if(enable_v4) { - add_port_service(family, "kerberos-iv", 750, "udp"); - add_port_service(family, "kerberos-iv", 750, "tcp"); + if(config->enable_v4) { + add_port_service(context, family, "kerberos-iv", 750, "udp"); + add_port_service(context, family, "kerberos-iv", 750, "tcp"); } - if (enable_kaserver) - add_port_service(family, "afs3-kaserver", 7004, "udp"); + if (config->enable_kaserver) + add_port_service(context, family, "afs3-kaserver", 7004, "udp"); } /* @@ -150,7 +165,9 @@ add_standard_ports (int family) */ static void -parse_ports(const char *str) +parse_ports(krb5_context context, + struct krb5_kdc_configuration *config, + const char *str) { char *pos = NULL; char *p; @@ -160,24 +177,24 @@ parse_ports(const char *str) while(p != NULL) { if(strcmp(p, "+") == 0) { #ifdef HAVE_IPV6 - add_standard_ports(AF_INET6); + add_standard_ports(context, config, AF_INET6); #endif - add_standard_ports(AF_INET); + add_standard_ports(context, config, AF_INET); } else { char *q = strchr(p, '/'); if(q){ *q++ = 0; #ifdef HAVE_IPV6 - add_port_string(AF_INET6, p, q); + add_port_string(context, AF_INET6, p, q); #endif - add_port_string(AF_INET, p, q); + add_port_string(context, AF_INET, p, q); }else { #ifdef HAVE_IPV6 - add_port_string(AF_INET6, p, "udp"); - add_port_string(AF_INET6, p, "tcp"); + add_port_string(context, AF_INET6, p, "udp"); + add_port_string(context, AF_INET6, p, "tcp"); #endif - add_port_string(AF_INET, p, "udp"); - add_port_string(AF_INET, p, "tcp"); + add_port_string(context, AF_INET, p, "udp"); + add_port_string(context, AF_INET, p, "tcp"); } } @@ -230,7 +247,9 @@ reinit_descrs (struct descr *d, int n) */ static void -init_socket(struct descr *d, krb5_address *a, int family, int type, int port) +init_socket(krb5_context context, + struct krb5_kdc_configuration *config, + struct descr *d, krb5_address *a, int family, int type, int port) { krb5_error_code ret; struct sockaddr_storage __ss; @@ -293,7 +312,9 @@ init_socket(struct descr *d, krb5_address *a, int family, int type, int port) */ static int -init_sockets(struct descr **desc) +init_sockets(krb5_context context, + struct krb5_kdc_configuration *config, + struct descr **desc) { krb5_error_code ret; int i, j; @@ -308,7 +329,7 @@ init_sockets(struct descr **desc) if (ret) krb5_err (context, 1, ret, "krb5_get_all_server_addrs"); } - parse_ports(port_str); + parse_ports(context, config, port_str); d = malloc(addresses.len * num_ports * sizeof(*d)); if (d == NULL) krb5_errx(context, 1, "malloc(%lu) failed", @@ -316,7 +337,7 @@ init_sockets(struct descr **desc) for (i = 0; i < num_ports; i++){ for (j = 0; j < addresses.len; ++j) { - init_socket(&d[num], &addresses.val[j], + init_socket(context, config, &d[num], &addresses.val[j], ports[i].family, ports[i].type, ports[i].port); if(d[num].s != -1){ char a_str[80]; @@ -325,7 +346,7 @@ init_sockets(struct descr **desc) krb5_print_address (&addresses.val[j], a_str, sizeof(a_str), &len); - kdc_log(5, "listening on %s port %u/%s", + kdc_log(context, config, 5, "listening on %s port %u/%s", a_str, ntohs(ports[i].port), (ports[i].type == SOCK_STREAM) ? "tcp" : "udp"); @@ -358,51 +379,9 @@ descr_type(struct descr *d) return "unknown"; } -/* - * handle the request in `buf, len', from `addr' (or `from' as a string), - * sending a reply in `reply'. - */ - -static int -process_request(unsigned char *buf, - size_t len, - krb5_data *reply, - krb5_boolean *prependlength, - const char *from, - struct sockaddr *addr) -{ - KDC_REQ req; - Ticket ticket; - krb5_error_code ret; - size_t i; - - gettimeofday(&now, NULL); - if(decode_AS_REQ(buf, len, &req, &i) == 0){ - ret = as_rep(&req, reply, from, addr); - free_AS_REQ(&req); - return ret; - }else if(decode_TGS_REQ(buf, len, &req, &i) == 0){ - ret = tgs_rep(&req, reply, from, addr); - free_TGS_REQ(&req); - return ret; - }else if(decode_Ticket(buf, len, &ticket, &i) == 0){ - ret = do_524(&ticket, reply, from, addr); - free_Ticket(&ticket); - return ret; - } else if(maybe_version4(buf, len)){ - *prependlength = FALSE; /* elbitapmoc sdrawkcab XXX */ - do_version4(buf, len, reply, from, (struct sockaddr_in*)addr); - return 0; - } else if (enable_kaserver) { - ret = do_kaserver (buf, len, reply, from, (struct sockaddr_in*)addr); - return ret; - } - - return -1; -} - static void -addr_to_string(struct sockaddr *addr, size_t addr_len, char *str, size_t len) +addr_to_string(krb5_context context, + struct sockaddr *addr, size_t addr_len, char *str, size_t len) { krb5_address a; if(krb5_sockaddr2address(context, addr, &a) == 0) { @@ -420,39 +399,45 @@ addr_to_string(struct sockaddr *addr, size_t addr_len, char *str, size_t len) */ static void -do_request(void *buf, size_t len, krb5_boolean prependlength, +do_request(krb5_context context, + struct krb5_kdc_configuration *config, + void *buf, size_t len, krb5_boolean prependlength, struct descr *d) { krb5_error_code ret; krb5_data reply; reply.length = 0; - ret = process_request(buf, len, &reply, &prependlength, + ret = krb5_kdc_process_generic_request(context, config, + buf, len, &reply, &prependlength, d->addr_string, d->sa); if(reply.length){ - kdc_log(5, "sending %lu bytes to %s", (unsigned long)reply.length, + kdc_log(context, config, 5, + "sending %lu bytes to %s", (unsigned long)reply.length, d->addr_string); if(prependlength){ - unsigned char len[4]; - len[0] = (reply.length >> 24) & 0xff; - len[1] = (reply.length >> 16) & 0xff; - len[2] = (reply.length >> 8) & 0xff; - len[3] = reply.length & 0xff; - if(sendto(d->s, len, sizeof(len), 0, d->sa, d->sock_len) < 0) { - kdc_log (0, "sendto(%s): %s", d->addr_string, strerror(errno)); + unsigned char l[4]; + l[0] = (reply.length >> 24) & 0xff; + l[1] = (reply.length >> 16) & 0xff; + l[2] = (reply.length >> 8) & 0xff; + l[3] = reply.length & 0xff; + if(sendto(d->s, l, sizeof(l), 0, d->sa, d->sock_len) < 0) { + kdc_log (context, config, + 0, "sendto(%s): %s", d->addr_string, strerror(errno)); krb5_data_free(&reply); return; } } if(sendto(d->s, reply.data, reply.length, 0, d->sa, d->sock_len) < 0) { - kdc_log (0, "sendto(%s): %s", d->addr_string, strerror(errno)); + kdc_log (context, config, + 0, "sendto(%s): %s", d->addr_string, strerror(errno)); krb5_data_free(&reply); return; } krb5_data_free(&reply); } if(ret) - kdc_log(0, "Failed processing %lu byte request from %s", + kdc_log(context, config, 0, "Failed processing %lu byte request from %s", (unsigned long)len, d->addr_string); } @@ -461,14 +446,16 @@ do_request(void *buf, size_t len, krb5_boolean prependlength, */ static void -handle_udp(struct descr *d) +handle_udp(krb5_context context, + struct krb5_kdc_configuration *config, + struct descr *d) { unsigned char *buf; int n; buf = malloc(max_request); if(buf == NULL){ - kdc_log(0, "Failed to allocate %lu bytes", (unsigned long)max_request); + kdc_log(context, config, 0, "Failed to allocate %lu bytes", (unsigned long)max_request); return; } @@ -477,9 +464,9 @@ handle_udp(struct descr *d) if(n < 0) krb5_warn(context, errno, "recvfrom"); else { - addr_to_string (d->sa, d->sock_len, + addr_to_string (context, d->sa, d->sock_len, d->addr_string, sizeof(d->addr_string)); - do_request(buf, n, FALSE, d); + do_request(context, config, buf, n, FALSE, d); } free (buf); } @@ -522,7 +509,9 @@ de_http(char *buf) */ static void -add_new_tcp (struct descr *d, int parent, int child) +add_new_tcp (krb5_context context, + struct krb5_kdc_configuration *config, + struct descr *d, int parent, int child) { int s; @@ -545,7 +534,8 @@ add_new_tcp (struct descr *d, int parent, int child) d[child].s = s; d[child].timeout = time(NULL) + TCP_TIMEOUT; d[child].type = SOCK_STREAM; - addr_to_string (d[child].sa, d[child].sock_len, + addr_to_string (context, + d[child].sa, d[child].sock_len, d[child].addr_string, sizeof(d[child].addr_string)); } @@ -555,7 +545,9 @@ add_new_tcp (struct descr *d, int parent, int child) */ static int -grow_descr (struct descr *d, size_t n) +grow_descr (krb5_context context, + struct krb5_kdc_configuration *config, + struct descr *d, size_t n) { if (d->size - d->len < n) { unsigned char *tmp; @@ -563,14 +555,14 @@ grow_descr (struct descr *d, size_t n) grow = max(1024, d->len + n); if (d->size + grow > max_request) { - kdc_log(0, "Request exceeds max request size (%lu bytes).", + kdc_log(context, config, 0, "Request exceeds max request size (%lu bytes).", (unsigned long)d->size + grow); clear_descr(d); return -1; } tmp = realloc (d->buf, d->size + grow); if (tmp == NULL) { - kdc_log(0, "Failed to re-allocate %lu bytes.", + kdc_log(context, config, 0, "Failed to re-allocate %lu bytes.", (unsigned long)d->size + grow); clear_descr(d); return -1; @@ -587,14 +579,16 @@ grow_descr (struct descr *d, size_t n) */ static int -handle_vanilla_tcp (struct descr *d) +handle_vanilla_tcp (krb5_context context, + struct krb5_kdc_configuration *config, + struct descr *d) { krb5_storage *sp; int32_t len; sp = krb5_storage_from_mem(d->buf, d->len); if (sp == NULL) { - kdc_log (0, "krb5_storage_from_mem failed"); + kdc_log (context, config, 0, "krb5_storage_from_mem failed"); return -1; } krb5_ret_int32(sp, &len); @@ -612,7 +606,9 @@ handle_vanilla_tcp (struct descr *d) */ static int -handle_http_tcp (struct descr *d) +handle_http_tcp (krb5_context context, + struct krb5_kdc_configuration *config, + struct descr *d) { char *s, *p, *t; void *data; @@ -623,7 +619,7 @@ handle_http_tcp (struct descr *d) p = strstr(s, "\r\n"); if (p == NULL) { - kdc_log(0, "Malformed HTTP request from %s", d->addr_string); + kdc_log(context, config, 0, "Malformed HTTP request from %s", d->addr_string); return -1; } *p = 0; @@ -631,31 +627,31 @@ handle_http_tcp (struct descr *d) p = NULL; t = strtok_r(s, " \t", &p); if (t == NULL) { - kdc_log(0, "Malformed HTTP request from %s", d->addr_string); + kdc_log(context, config, 0, "Malformed HTTP request from %s", d->addr_string); return -1; } t = strtok_r(NULL, " \t", &p); if(t == NULL) { - kdc_log(0, "Malformed HTTP request from %s", d->addr_string); + kdc_log(context, config, 0, "Malformed HTTP request from %s", d->addr_string); return -1; } data = malloc(strlen(t)); if (data == NULL) { - kdc_log(0, "Failed to allocate %lu bytes", + kdc_log(context, config, 0, "Failed to allocate %lu bytes", (unsigned long)strlen(t)); return -1; } if(*t == '/') t++; if(de_http(t) != 0) { - kdc_log(0, "Malformed HTTP request from %s", d->addr_string); - kdc_log(5, "HTTP request: %s", t); + kdc_log(context, config, 0, "Malformed HTTP request from %s", d->addr_string); + kdc_log(context, config, 5, "HTTP request: %s", t); free(data); return -1; } proto = strtok_r(NULL, " \t", &p); if (proto == NULL) { - kdc_log(0, "Malformed HTTP request from %s", d->addr_string); + kdc_log(context, config, 0, "Malformed HTTP request from %s", d->addr_string); free(data); return -1; } @@ -672,16 +668,16 @@ handle_http_tcp (struct descr *d) "

404 Not found

\r\n" "That page doesn't exist, maybe you are looking for " "Heimdal?\r\n"; - kdc_log(0, "HTTP request from %s is non KDC request", d->addr_string); - kdc_log(5, "HTTP request: %s", t); + kdc_log(context, config, 0, "HTTP request from %s is non KDC request", d->addr_string); + kdc_log(context, config, 5, "HTTP request: %s", t); free(data); if (write(d->s, proto, strlen(proto)) < 0) { - kdc_log(0, "HTTP write failed: %s: %s", + kdc_log(context, config, 0, "HTTP write failed: %s: %s", d->addr_string, strerror(errno)); return -1; } if (write(d->s, msg, strlen(msg)) < 0) { - kdc_log(0, "HTTP write failed: %s: %s", + kdc_log(context, config, 0, "HTTP write failed: %s: %s", d->addr_string, strerror(errno)); return -1; } @@ -696,12 +692,12 @@ handle_http_tcp (struct descr *d) "Content-type: application/octet-stream\r\n" "Content-transfer-encoding: binary\r\n\r\n"; if (write(d->s, proto, strlen(proto)) < 0) { - kdc_log(0, "HTTP write failed: %s: %s", + kdc_log(context, config, 0, "HTTP write failed: %s: %s", d->addr_string, strerror(errno)); return -1; } if (write(d->s, msg, strlen(msg)) < 0) { - kdc_log(0, "HTTP write failed: %s: %s", + kdc_log(context, config, 0, "HTTP write failed: %s: %s", d->addr_string, strerror(errno)); return -1; } @@ -717,67 +713,72 @@ handle_http_tcp (struct descr *d) */ static void -handle_tcp(struct descr *d, int index, int min_free) +handle_tcp(krb5_context context, + struct krb5_kdc_configuration *config, + struct descr *d, int idx, int min_free) { unsigned char buf[1024]; int n; int ret = 0; - if (d[index].timeout == 0) { - add_new_tcp (d, index, min_free); + if (d[idx].timeout == 0) { + add_new_tcp (context, config, d, idx, min_free); return; } - n = recvfrom(d[index].s, buf, sizeof(buf), 0, NULL, NULL); + n = recvfrom(d[idx].s, buf, sizeof(buf), 0, NULL, NULL); if(n < 0){ krb5_warn(context, errno, "recvfrom failed from %s to %s/%d", - d[index].addr_string, descr_type(d + index), - ntohs(d[index].port)); + d[idx].addr_string, descr_type(d + idx), + ntohs(d[idx].port)); return; } else if (n == 0) { krb5_warnx(context, "connection closed before end of data after %lu " - "bytes from %s to %s/%d", (unsigned long)d[index].len, - d[index].addr_string, descr_type(d + index), - ntohs(d[index].port)); - clear_descr (d + index); + "bytes from %s to %s/%d", (unsigned long)d[idx].len, + d[idx].addr_string, descr_type(d + idx), + ntohs(d[idx].port)); + clear_descr (d + idx); return; } - if (grow_descr (&d[index], n)) + if (grow_descr (context, config, &d[idx], n)) return; - memcpy(d[index].buf + d[index].len, buf, n); - d[index].len += n; - if(d[index].len > 4 && d[index].buf[0] == 0) { - ret = handle_vanilla_tcp (&d[index]); + memcpy(d[idx].buf + d[idx].len, buf, n); + d[idx].len += n; + if(d[idx].len > 4 && d[idx].buf[0] == 0) { + ret = handle_vanilla_tcp (context, config, &d[idx]); } else if(enable_http && - d[index].len >= 4 && - strncmp((char *)d[index].buf, "GET ", 4) == 0 && - strncmp((char *)d[index].buf + d[index].len - 4, + d[idx].len >= 4 && + strncmp((char *)d[idx].buf, "GET ", 4) == 0 && + strncmp((char *)d[idx].buf + d[idx].len - 4, "\r\n\r\n", 4) == 0) { - ret = handle_http_tcp (&d[index]); + ret = handle_http_tcp (context, config, &d[idx]); if (ret < 0) - clear_descr (d + index); - } else if (d[index].len > 4) { - kdc_log (0, "TCP data of strange type from %s to %s/%d", - d[index].addr_string, descr_type(d + index), - ntohs(d[index].port)); - clear_descr(d + index); + clear_descr (d + idx); + } else if (d[idx].len > 4) { + kdc_log (context, config, + 0, "TCP data of strange type from %s to %s/%d", + d[idx].addr_string, descr_type(d + idx), + ntohs(d[idx].port)); + clear_descr(d + idx); return; } if (ret < 0) return; else if (ret == 1) { - do_request(d[index].buf, d[index].len, TRUE, &d[index]); - clear_descr(d + index); + do_request(context, config, + d[idx].buf, d[idx].len, TRUE, &d[idx]); + clear_descr(d + idx); } } void -loop(void) +loop(krb5_context context, + struct krb5_kdc_configuration *config) { struct descr *d; int ndescr; - ndescr = init_sockets(&d); + ndescr = init_sockets(context, config, &d); if(ndescr <= 0) krb5_errx(context, 1, "No sockets!"); while(exit_flag == 0){ @@ -792,7 +793,8 @@ loop(void) if(d[i].s >= 0){ if(d[i].type == SOCK_STREAM && d[i].timeout && d[i].timeout < time(NULL)) { - kdc_log(1, "TCP-connection from %s expired after %lu bytes", + kdc_log(context, config, 1, + "TCP-connection from %s expired after %lu bytes", d[i].addr_string, (unsigned long)d[i].len); clear_descr(&d[i]); continue; @@ -834,17 +836,17 @@ loop(void) for(i = 0; i < ndescr; i++) if(d[i].s >= 0 && FD_ISSET(d[i].s, &fds)) { if(d[i].type == SOCK_DGRAM) - handle_udp(&d[i]); + handle_udp(context, config, &d[i]); else if(d[i].type == SOCK_STREAM) - handle_tcp(d, i, min_free); + handle_tcp(context, config, d, i, min_free); } } } if(exit_flag == SIGXCPU) - kdc_log(0, "CPU time limit exceeded"); + kdc_log(context, config, 0, "CPU time limit exceeded"); else if(exit_flag == SIGINT || exit_flag == SIGTERM) - kdc_log(0, "Terminated"); + kdc_log(context, config, 0, "Terminated"); else - kdc_log(0, "Unexpected exit reason: %d", exit_flag); + kdc_log(context, config, 0, "Unexpected exit reason: %d", exit_flag); free (d); } diff --git a/kdc/hprop.c b/kdc/hprop.c index 19352799b..7b9c23c25 100644 --- a/kdc/hprop.c +++ b/kdc/hprop.c @@ -586,7 +586,7 @@ parse_source_type(const char *s) static void iterate (krb5_context context, - const char *database, + const char *database_name, HDB *db, int type, struct prop_data *pd) @@ -595,7 +595,7 @@ iterate (krb5_context context, switch(type) { case HPROP_KRB4_DUMP: - ret = v4_prop_dump(pd, database); + ret = v4_prop_dump(pd, database_name); break; #ifdef KRB4 case HPROP_KRB4_DB: @@ -606,12 +606,12 @@ iterate (krb5_context context, break; #endif /* KRB4 */ case HPROP_KASERVER: - ret = ka_dump(pd, database); + ret = ka_dump(pd, database_name); if(ret) krb5_err(context, 1, ret, "ka_dump"); break; case HPROP_MIT_DUMP: - ret = mit_prop_dump(pd, database); + ret = mit_prop_dump(pd, database_name); if (ret) krb5_errx(context, 1, "mit_prop_dump: %s", krb5_get_err_text(context, ret)); @@ -626,7 +626,7 @@ iterate (krb5_context context, static int dump_database (krb5_context context, int type, - const char *database, HDB *db) + const char *database_name, HDB *db) { krb5_error_code ret; struct prop_data pd; @@ -636,7 +636,7 @@ dump_database (krb5_context context, int type, pd.auth_context = NULL; pd.sock = STDOUT_FILENO; - iterate (context, database, db, type, &pd); + iterate (context, database_name, db, type, &pd); krb5_data_zero (&data); ret = krb5_write_message (context, &pd.sock, &data); if (ret) @@ -647,15 +647,15 @@ dump_database (krb5_context context, int type, static int propagate_database (krb5_context context, int type, - const char *database, + const char *database_name, HDB *db, krb5_ccache ccache, - int optind, int argc, char **argv) + int optidx, int argc, char **argv) { krb5_principal server; krb5_error_code ret; int i; - for(i = optind; i < argc; i++){ + for(i = optidx; i < argc; i++){ krb5_auth_context auth_context; int fd; struct prop_data pd; @@ -721,7 +721,7 @@ propagate_database (krb5_context context, int type, pd.auth_context = auth_context; pd.sock = fd; - iterate (context, database, db, type, &pd); + iterate (context, database_name, db, type, &pd); krb5_data_zero (&data); ret = krb5_write_priv_message(context, auth_context, &fd, &data); @@ -747,13 +747,13 @@ main(int argc, char **argv) krb5_context context; krb5_ccache ccache = NULL; HDB *db = NULL; - int optind = 0; + int optidx = 0; int type = 0; setprogname(argv[0]); - if(getarg(args, num_args, argc, argv, &optind)) + if(getarg(args, num_args, argc, argv, &optidx)) usage(1); if(help_flag) @@ -865,7 +865,7 @@ main(int argc, char **argv) dump_database (context, type, database, db); else propagate_database (context, type, database, - db, ccache, optind, argc, argv); + db, ccache, optidx, argc, argv); if(ccache != NULL) krb5_cc_destroy(context, ccache); diff --git a/kdc/hpropd.c b/kdc/hpropd.c index 6cfbb8482..865cdcbfa 100644 --- a/kdc/hpropd.c +++ b/kdc/hpropd.c @@ -215,7 +215,7 @@ main(int argc, char **argv) krb5_keytab keytab; int fd; HDB *db; - int optind = 0; + int optidx = 0; char *tmp_db; krb5_log_facility *fac; int nprincs; @@ -235,7 +235,7 @@ main(int argc, char **argv) ; krb5_set_warn_dest(context, fac); - if(getarg(args, num_args, argc, argv, &optind)) + if(getarg(args, num_args, argc, argv, &optidx)) usage(1); #ifdef KRB4 @@ -253,8 +253,8 @@ main(int argc, char **argv) exit(0); } - argc -= optind; - argv += optind; + argc -= optidx; + argv += optidx; if (argc != 0) usage(1); diff --git a/kdc/kaserver.c b/kdc/kaserver.c index b7a66b8e0..d23384eb7 100644 --- a/kdc/kaserver.c +++ b/kdc/kaserver.c @@ -240,7 +240,8 @@ krb5_store_xdr_data(krb5_storage *sp, static krb5_error_code -create_reply_ticket (struct rx_header *hdr, +create_reply_ticket (krb5_context context, + struct rx_header *hdr, Key *skey, char *name, char *instance, char *realm, struct sockaddr_in *addr, @@ -388,7 +389,9 @@ unparse_auth_args (krb5_storage *sp, } static void -do_authenticate (struct rx_header *hdr, +do_authenticate (krb5_context context, + struct krb5_kdc_configuration *config, + struct rx_header *hdr, krb5_storage *sp, struct sockaddr_in *addr, const char *from, @@ -422,30 +425,33 @@ do_authenticate (struct rx_header *hdr, } snprintf (client_name, sizeof(client_name), "%s.%s@%s", - name, instance, v4_realm); + name, instance, config->v4_realm); snprintf (server_name, sizeof(server_name), "%s.%s@%s", - "krbtgt", v4_realm, v4_realm); + "krbtgt", config->v4_realm, config->v4_realm); - kdc_log(0, "AS-REQ (kaserver) %s from %s for %s", + kdc_log(context, config, 0, "AS-REQ (kaserver) %s from %s for %s", client_name, from, server_name); - ret = db_fetch4 (name, instance, v4_realm, &client_entry); + ret = db_fetch4 (context, config, name, instance, + config->v4_realm, &client_entry); if (ret) { - kdc_log(0, "Client not found in database: %s: %s", + kdc_log(context, config, 0, "Client not found in database: %s: %s", client_name, krb5_get_err_text(context, ret)); make_error_reply (hdr, KANOENT, reply); goto out; } - ret = db_fetch4 ("krbtgt", v4_realm, v4_realm, &server_entry); + ret = db_fetch4 (context, config, "krbtgt", + config->v4_realm, config->v4_realm, &server_entry); if (ret) { - kdc_log(0, "Server not found in database: %s: %s", + kdc_log(context, config, 0, "Server not found in database: %s: %s", server_name, krb5_get_err_text(context, ret)); make_error_reply (hdr, KANOENT, reply); goto out; } - ret = check_flags (client_entry, client_name, + ret = check_flags (context, config, + client_entry, client_name, server_entry, server_name, TRUE); if (ret) { @@ -454,17 +460,17 @@ do_authenticate (struct rx_header *hdr, } /* find a DES key */ - ret = get_des_key(client_entry, FALSE, TRUE, &ckey); + ret = get_des_key(context, client_entry, FALSE, TRUE, &ckey); if(ret){ - kdc_log(0, "no suitable DES key for client"); + kdc_log(context, config, 0, "no suitable DES key for client"); make_error_reply (hdr, KANOKEYS, reply); goto out; } /* find a DES key */ - ret = get_des_key(server_entry, TRUE, TRUE, &skey); + ret = get_des_key(context, server_entry, TRUE, TRUE, &skey); if(ret){ - kdc_log(0, "no suitable DES key for server"); + kdc_log(context, config, 0, "no suitable DES key for server"); make_error_reply (hdr, KANOKEYS, reply); goto out; } @@ -488,7 +494,7 @@ do_authenticate (struct rx_header *hdr, /* check for the magic label */ if (memcmp ((char *)request.data + 4, "gTGS", 4) != 0) { - kdc_log(0, "preauth failed for %s", client_name); + kdc_log(context, config, 0, "preauth failed for %s", client_name); make_error_reply (hdr, KABADREQUEST, reply); goto out; } @@ -515,11 +521,12 @@ do_authenticate (struct rx_header *hdr, life = krb_time_to_life(kdc_time, kdc_time + max_life); - create_reply_ticket (hdr, skey, - name, instance, v4_realm, + create_reply_ticket (context, + hdr, skey, + name, instance, config->v4_realm, addr, life, server_entry->kvno, max_seq_len, - "krbtgt", v4_realm, + "krbtgt", config->v4_realm, chal + 1, "tgsT", &ckey->key, reply); @@ -533,9 +540,9 @@ out: if (instance) free (instance); if (client_entry) - free_ent (client_entry); + free_ent (context, client_entry); if (server_entry) - free_ent (server_entry); + free_ent (context, server_entry); } static krb5_error_code @@ -593,7 +600,9 @@ unparse_getticket_args (krb5_storage *sp, } static void -do_getticket (struct rx_header *hdr, +do_getticket (krb5_context context, + struct krb5_kdc_configuration *config, + struct rx_header *hdr, krb5_storage *sp, struct sockaddr_in *addr, const char *from, @@ -636,36 +645,39 @@ do_getticket (struct rx_header *hdr, } snprintf (server_name, sizeof(server_name), - "%s.%s@%s", name, instance, v4_realm); + "%s.%s@%s", name, instance, config->v4_realm); - ret = db_fetch4 (name, instance, v4_realm, &server_entry); + ret = db_fetch4 (context, config, name, instance, config->v4_realm, &server_entry); if (ret) { - kdc_log(0, "Server not found in database: %s: %s", + kdc_log(context, config, 0, "Server not found in database: %s: %s", server_name, krb5_get_err_text(context, ret)); make_error_reply (hdr, KANOENT, reply); goto out; } - ret = db_fetch4 ("krbtgt", v4_realm, v4_realm, &krbtgt_entry); + ret = db_fetch4 (context, config, "krbtgt", + config->v4_realm, config->v4_realm, &krbtgt_entry); if (ret) { - kdc_log(0, "Server not found in database: %s.%s@%s: %s", - "krbtgt", v4_realm, v4_realm, krb5_get_err_text(context, ret)); + kdc_log(context, config, 0, + "Server not found in database: %s.%s@%s: %s", + "krbtgt", config->v4_realm, config->v4_realm, + krb5_get_err_text(context, ret)); make_error_reply (hdr, KANOENT, reply); goto out; } /* find a DES key */ - ret = get_des_key(krbtgt_entry, TRUE, TRUE, &kkey); + ret = get_des_key(context, krbtgt_entry, TRUE, TRUE, &kkey); if(ret){ - kdc_log(0, "no suitable DES key for krbtgt"); + kdc_log(context, config, 0, "no suitable DES key for krbtgt"); make_error_reply (hdr, KANOKEYS, reply); goto out; } /* find a DES key */ - ret = get_des_key(server_entry, TRUE, TRUE, &skey); + ret = get_des_key(context, server_entry, TRUE, TRUE, &skey); if(ret){ - kdc_log(0, "no suitable DES key for server"); + kdc_log(context, config, 0, "no suitable DES key for server"); make_error_reply (hdr, KANOKEYS, reply); goto out; } @@ -679,17 +691,19 @@ do_getticket (struct rx_header *hdr, char *sinstance = NULL; ret = _krb5_krb_decomp_ticket(context, &aticket, &kkey->key, - v4_realm, &sname, &sinstance, &ad); + config->v4_realm, &sname, + &sinstance, &ad); if (ret) { - kdc_log(0, "kaserver: decomp failed for %s.%s with %d", + kdc_log(context, config, 0, + "kaserver: decomp failed for %s.%s with %d", sname, sinstance, ret); make_error_reply (hdr, KABADTICKET, reply); goto out; } if (strcmp (sname, "krbtgt") != 0 - || strcmp (sinstance, v4_realm) != 0) { - kdc_log(0, "no TGT: %s.%s for %s.%s@%s", + || strcmp (sinstance, config->v4_realm) != 0) { + kdc_log(context, config, 0, "no TGT: %s.%s for %s.%s@%s", sname, sinstance, ad.pname, ad.pinst, ad.prealm); make_error_reply (hdr, KABADTICKET, reply); @@ -701,7 +715,7 @@ do_getticket (struct rx_header *hdr, free(sinstance); if (kdc_time > _krb5_krb_life_to_time(ad.time_sec, ad.life)) { - kdc_log(0, "TGT expired: %s.%s@%s", + kdc_log(context, config, 0, "TGT expired: %s.%s@%s", ad.pname, ad.pinst, ad.prealm); make_error_reply (hdr, KABADTICKET, reply); goto out; @@ -711,24 +725,28 @@ do_getticket (struct rx_header *hdr, snprintf (client_name, sizeof(client_name), "%s.%s@%s", ad.pname, ad.pinst, ad.prealm); - kdc_log(0, "TGS-REQ (kaserver) %s from %s for %s", + kdc_log(context, config, 0, "TGS-REQ (kaserver) %s from %s for %s", client_name, from, server_name); - ret = db_fetch4 (ad.pname, ad.pinst, ad.prealm, &client_entry); + ret = db_fetch4 (context, config, + ad.pname, ad.pinst, ad.prealm, &client_entry); if(ret && ret != HDB_ERR_NOENTRY) { - kdc_log(0, "Client not found in database: (krb4) %s: %s", + kdc_log(context, config, 0, + "Client not found in database: (krb4) %s: %s", client_name, krb5_get_err_text(context, ret)); make_error_reply (hdr, KANOENT, reply); goto out; } - if (client_entry == NULL && strcmp(ad.prealm, v4_realm) == 0) { - kdc_log(0, "Local client not found in database: (krb4) " + if (client_entry == NULL && strcmp(ad.prealm, config->v4_realm) == 0) { + kdc_log(context, config, 0, + "Local client not found in database: (krb4) " "%s", client_name); make_error_reply (hdr, KANOENT, reply); goto out; } - ret = check_flags (client_entry, client_name, + ret = check_flags (context, config, + client_entry, client_name, server_entry, server_name, FALSE); if (ret) { @@ -776,7 +794,8 @@ do_getticket (struct rx_header *hdr, life = _krb5_krb_time_to_life(kdc_time, kdc_time + max_life); - create_reply_ticket (hdr, skey, + create_reply_ticket (context, + hdr, skey, ad.pname, ad.pinst, ad.prealm, addr, life, server_entry->kvno, max_seq_len, @@ -801,13 +820,15 @@ out: if (instance) free (instance); if (krbtgt_entry) - free_ent (krbtgt_entry); + free_ent (context, krbtgt_entry); if (server_entry) - free_ent (server_entry); + free_ent (context, server_entry); } krb5_error_code -do_kaserver(unsigned char *buf, +do_kaserver(krb5_context context, + struct krb5_kdc_configuration *config, + unsigned char *buf, size_t len, krb5_data *reply, const char *from, @@ -852,10 +873,10 @@ do_kaserver(unsigned char *buf, switch (op) { case AUTHENTICATE : case AUTHENTICATE_V2 : - do_authenticate (&hdr, sp, addr, from, reply); + do_authenticate (context, config, &hdr, sp, addr, from, reply); break; case GETTICKET : - do_getticket (&hdr, sp, addr, from, reply); + do_getticket (context, config, &hdr, sp, addr, from, reply); break; case AUTHENTICATE_OLD : case CHANGEPASSWORD : diff --git a/kdc/kdc-protos.h b/kdc/kdc-protos.h new file mode 100644 index 000000000..7761625bc --- /dev/null +++ b/kdc/kdc-protos.h @@ -0,0 +1,24 @@ + +int +krb5_kdc_process_generic_request(krb5_context context, + struct krb5_kdc_configuration *config, + unsigned char *buf, + size_t len, + krb5_data *reply, + krb5_boolean *prependlength, + const char *from, + struct sockaddr *addr); + +int krb5_kdc_process_krb5_request(krb5_context context, + struct krb5_kdc_configuration *config, + unsigned char *buf, + size_t len, + krb5_data *reply, + const char *from, + struct sockaddr *addr); + +void krb5_kdc_default_config(struct krb5_kdc_configuration *config); + +void +kdc_openlog(krb5_context context, + struct krb5_kdc_configuration *config); diff --git a/kdc/kdc.h b/kdc/kdc.h new file mode 100644 index 000000000..57c49fdc1 --- /dev/null +++ b/kdc/kdc.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 1997-2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * + * Copyright (c) 2005 Andrew Bartlett + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef __KDC_H__ +#define __KDC_H__ + +#include + +enum krb5_kdc_trpolicy { + TRPOLICY_ALWAYS_CHECK, + TRPOLICY_ALLOW_PER_PRINCIPAL, + TRPOLICY_ALWAYS_HONOUR_REQUEST +}; + +struct krb5_kdc_configuration { + krb5_boolean require_preauth; /* require preauth for all principals */ + time_t kdc_warn_pwexpire; /* time before expiration to print a warning */ + + struct HDB **db; + int num_db; + + krb5_boolean encode_as_rep_as_tgs_rep; /* bug compatibility */ + + krb5_boolean check_ticket_addresses; + krb5_boolean allow_null_ticket_addresses; + krb5_boolean allow_anonymous; + enum krb5_kdc_trpolicy trpolicy; + + char *v4_realm; + krb5_boolean enable_v4; + krb5_boolean enable_kaserver; + + krb5_boolean enable_524; + krb5_boolean enable_v4_cross_realm; + + krb5_boolean enable_pkinit; + krb5_boolean enable_pkinit_princ_in_cert; + + krb5_log_facility *logf; +}; + +#include + +#endif diff --git a/kdc/kdc_locl.h b/kdc/kdc_locl.h index 2c65b5921..18cd41132 100644 --- a/kdc/kdc_locl.h +++ b/kdc/kdc_locl.h @@ -39,40 +39,18 @@ #define __KDC_LOCL_H__ #include "headers.h" +#include "kdc.h" -extern krb5_context context; - -extern int require_preauth; extern sig_atomic_t exit_flag; extern size_t max_request; -extern time_t kdc_warn_pwexpire; -extern struct dbinfo { - char *realm; - char *dbname; - char *mkey_file; - struct dbinfo *next; -} *databases; -extern HDB **db; -extern int num_db; extern const char *port_str; extern krb5_addresses explicit_addresses; extern int enable_http; -extern krb5_boolean encode_as_rep_as_tgs_rep; -extern krb5_boolean check_ticket_addresses; -extern krb5_boolean allow_null_ticket_addresses; -extern krb5_boolean allow_anonymous; -enum { TRPOLICY_ALWAYS_CHECK, - TRPOLICY_ALLOW_PER_PRINCIPAL, - TRPOLICY_ALWAYS_HONOUR_REQUEST }; -extern int trpolicy; -extern int enable_524; -extern int enable_v4_cross_realm; -#ifdef PKINIT -extern int enable_pkinit; -extern int enable_pkinit_princ_in_cert; -#endif +#define DETACH_IS_DEFAULT FALSE + +extern int detach_from_console; #define _PATH_KDC_CONF HDB_DB_DIR "/kdc.conf" #define DEFAULT_LOG_DEST "0-1/FILE:" HDB_DB_DIR "/kdc.log" @@ -80,30 +58,56 @@ extern int enable_pkinit_princ_in_cert; extern struct timeval now; #define kdc_time (now.tv_sec) -krb5_error_code as_rep (KDC_REQ*, krb5_data*, const char*, struct sockaddr*); -void configure (int, char**); -krb5_error_code db_fetch (krb5_principal, hdb_entry**); -void free_ent(hdb_entry *); -void kdc_log (int, const char*, ...) - __attribute__ ((format (printf, 2,3))); +krb5_error_code as_rep (krb5_context context, + struct krb5_kdc_configuration *config, + KDC_REQ*, krb5_data*, const char*, struct sockaddr*); +struct krb5_kdc_configuration *configure(krb5_context context, int argc, char **argv); +krb5_error_code +db_fetch(krb5_context, struct krb5_kdc_configuration *, + krb5_principal, hdb_entry **); +void free_ent(krb5_context context, hdb_entry *); +void kdc_log (krb5_context context, + struct krb5_kdc_configuration *config, + int, const char*, ...) + __attribute__ ((format (printf, 4,5))); -char* kdc_log_msg (int, const char*, ...) - __attribute__ ((format (printf, 2,3))); -char* kdc_log_msg_va (int, const char*, va_list) - __attribute__ ((format (printf, 2,0))); -void kdc_openlog (void); -void loop (void); +char* kdc_log_msg (krb5_context context, + struct krb5_kdc_configuration *config, + int, const char*, ...) + __attribute__ ((format (printf, 4,5))); +char* kdc_log_msg_va (krb5_context context, + struct krb5_kdc_configuration *config, + int, const char*, va_list) + __attribute__ ((format (printf, 4,0))); +void +kdc_openlog(krb5_context context, + struct krb5_kdc_configuration *config); +void +loop(krb5_context context, + struct krb5_kdc_configuration *config); void set_master_key (EncryptionKey); -krb5_error_code tgs_rep (KDC_REQ*, krb5_data*, const char*, struct sockaddr *); +krb5_error_code tgs_rep (krb5_context context, + struct krb5_kdc_configuration *config, + KDC_REQ*, krb5_data*, const char*, struct sockaddr *); Key* unseal_key (Key*); -krb5_error_code check_flags(hdb_entry *client, const char *client_name, +krb5_error_code +check_flags(krb5_context context, + struct krb5_kdc_configuration *config, + hdb_entry *client, const char *client_name, hdb_entry *server, const char *server_name, krb5_boolean is_as_req); -krb5_error_code get_des_key(hdb_entry*, krb5_boolean, krb5_boolean, Key**); -krb5_error_code encode_v4_ticket (void*, size_t, const EncTicketPart*, - const PrincipalName*, size_t*); -krb5_error_code do_524 (const Ticket*, krb5_data*, const char*, struct sockaddr*); +krb5_error_code get_des_key(krb5_context context, hdb_entry*, krb5_boolean, krb5_boolean, Key**); +krb5_error_code +encode_v4_ticket(krb5_context context, + struct krb5_kdc_configuration *config, + void *buf, size_t len, const EncTicketPart *et, + const PrincipalName *service, size_t *size); +krb5_error_code +do_524(krb5_context context, + struct krb5_kdc_configuration *config, + const Ticket *t, krb5_data *reply, + const char *from, struct sockaddr *addr); #ifdef HAVE_OPENSSL #define des_new_random_key des_random_key @@ -130,18 +134,27 @@ void pk_free_client_param(krb5_context, pk_client_params *); * Kerberos 4 */ -extern char *v4_realm; -extern int enable_v4; -extern krb5_boolean enable_kaserver; - -krb5_error_code db_fetch4 (const char*, const char*, const char*, hdb_entry**); -krb5_error_code do_version4 (unsigned char*, size_t, krb5_data*, const char*, +krb5_error_code db_fetch4 (krb5_context context, + struct krb5_kdc_configuration *config, + const char*, const char*, const char*, hdb_entry**); +krb5_error_code do_version4 (krb5_context context, + struct krb5_kdc_configuration *config, + unsigned char*, size_t, krb5_data*, const char*, struct sockaddr_in*); int maybe_version4 (unsigned char*, int); -krb5_error_code do_kaserver (unsigned char*, size_t, krb5_data*, const char*, +krb5_error_code do_kaserver (krb5_context context, + struct krb5_kdc_configuration *config, + unsigned char*, size_t, krb5_data*, const char*, struct sockaddr_in*); - +int kdc_process_generic_request(krb5_context context, + struct krb5_kdc_configuration *config, + unsigned char *buf, + size_t len, + krb5_data *reply, + krb5_boolean *prependlength, + const char *from, + struct sockaddr *addr); #endif /* __KDC_LOCL_H__ */ diff --git a/kdc/kerberos4.c b/kdc/kerberos4.c index 81a3bd5a2..5c6d9d0fc 100644 --- a/kdc/kerberos4.c +++ b/kdc/kerberos4.c @@ -63,8 +63,11 @@ make_err_reply(krb5_context context, krb5_data *reply, } static krb5_boolean -valid_princ(krb5_context context, krb5_principal princ) +valid_princ(krb5_context context, + void *funcctx, + krb5_principal princ) { + struct krb5_kdc_configuration *config = funcctx; krb5_error_code ret; char *s; hdb_entry *ent; @@ -72,31 +75,33 @@ valid_princ(krb5_context context, krb5_principal princ) ret = krb5_unparse_name(context, princ, &s); if (ret) return FALSE; - ret = db_fetch(princ, &ent); + ret = db_fetch(context, config, princ, &ent); if (ret) { - kdc_log(7, "Lookup %s failed: %s", s, + kdc_log(context, config, 7, "Lookup %s failed: %s", s, krb5_get_err_text (context, ret)); free(s); return FALSE; } - kdc_log(7, "Lookup %s succeeded", s); + kdc_log(context, config, 7, "Lookup %s succeeded", s); free(s); - free_ent(ent); + free_ent(context, ent); return TRUE; } krb5_error_code -db_fetch4(const char *name, const char *instance, const char *realm, +db_fetch4(krb5_context context, + struct krb5_kdc_configuration *config, + const char *name, const char *instance, const char *realm, hdb_entry **ent) { krb5_principal p; krb5_error_code ret; - ret = krb5_425_conv_principal_ext(context, name, instance, realm, - valid_princ, 0, &p); + ret = krb5_425_conv_principal_ext2(context, name, instance, realm, + valid_princ, config, 0, &p); if(ret) return ret; - ret = db_fetch(p, ent); + ret = db_fetch(context, config, p, ent); krb5_free_principal(context, p); return ret; } @@ -110,7 +115,9 @@ db_fetch4(const char *name, const char *instance, const char *realm, */ krb5_error_code -do_version4(unsigned char *buf, +do_version4(krb5_context context, + struct krb5_kdc_configuration *config, + unsigned char *buf, size_t len, krb5_data *reply, const char *from, @@ -131,8 +138,9 @@ do_version4(unsigned char *buf, char client_name[256]; char server_name[256]; - if(!enable_v4) { - kdc_log(0, "Rejected version 4 request from %s", from); + if(!config->enable_v4) { + kdc_log(context, config, 0, + "Rejected version 4 request from %s", from); make_err_reply(context, reply, KDC_GEN_ERR, "function not enabled"); return 0; } @@ -140,7 +148,8 @@ do_version4(unsigned char *buf, sp = krb5_storage_from_mem(buf, len); RCHECK(krb5_ret_int8(sp, &pvno), out); if(pvno != 4){ - kdc_log(0, "Protocol version mismatch (krb4) (%d)", pvno); + kdc_log(context, config, 0, + "Protocol version mismatch (krb4) (%d)", pvno); make_err_reply(context, reply, KDC_PKT_VER, "protocol mismatch"); goto out; } @@ -167,29 +176,31 @@ do_version4(unsigned char *buf, snprintf (client_name, sizeof(client_name), "%s.%s@%s", name, inst, realm); snprintf (server_name, sizeof(server_name), - "%s.%s@%s", sname, sinst, v4_realm); + "%s.%s@%s", sname, sinst, config->v4_realm); - kdc_log(0, "AS-REQ (krb4) %s from %s for %s", + kdc_log(context, config, 0, "AS-REQ (krb4) %s from %s for %s", client_name, from, server_name); - ret = db_fetch4(name, inst, realm, &client); + ret = db_fetch4(context, config, name, inst, realm, &client); if(ret) { - kdc_log(0, "Client not found in database: %s: %s", + kdc_log(context, config, 0, "Client not found in database: %s: %s", client_name, krb5_get_err_text(context, ret)); make_err_reply(context, reply, KERB_ERR_PRINCIPAL_UNKNOWN, "principal unknown"); goto out1; } - ret = db_fetch4(sname, sinst, v4_realm, &server); + ret = db_fetch4(context, config, sname, sinst, + config->v4_realm, &server); if(ret){ - kdc_log(0, "Server not found in database: %s: %s", + kdc_log(context, config, 0, "Server not found in database: %s: %s", server_name, krb5_get_err_text(context, ret)); make_err_reply(context, reply, KERB_ERR_PRINCIPAL_UNKNOWN, "principal unknown"); goto out1; } - ret = check_flags (client, client_name, + ret = check_flags (context, config, + client, client_name, server, server_name, TRUE); if (ret) { @@ -204,10 +215,10 @@ do_version4(unsigned char *buf, * good error code to return if preauthentication is required. */ - if (require_preauth + if (config->require_preauth || client->flags.require_preauth || server->flags.require_preauth) { - kdc_log(0, + kdc_log(context, config, 0, "Pre-authentication required for v4-request: " "%s for %s", client_name, server_name); @@ -216,9 +227,9 @@ do_version4(unsigned char *buf, goto out1; } - ret = get_des_key(client, FALSE, FALSE, &ckey); + ret = get_des_key(context, client, FALSE, FALSE, &ckey); if(ret){ - kdc_log(0, "no suitable DES key for client"); + kdc_log(context, config, 0, "no suitable DES key for client"); make_err_reply(context, reply, KDC_NULL_KEY, "no suitable DES key for client"); goto out1; @@ -230,7 +241,7 @@ do_version4(unsigned char *buf, while(ckey->salt == NULL || ckey->salt->salt.length != 0) ret = hdb_next_keytype2key(context, client, KEYTYPE_DES, &ckey); if(ret){ - kdc_log(0, "No version-4 salted key in database -- %s.%s@%s", + kdc_log(context, config, 0, "No version-4 salted key in database -- %s.%s@%s", name, inst, realm); make_err_reply(context, reply, KDC_NULL_KEY, "No version-4 salted key in database"); @@ -238,9 +249,9 @@ do_version4(unsigned char *buf, } #endif - ret = get_des_key(server, TRUE, FALSE, &skey); + ret = get_des_key(context, server, TRUE, FALSE, &skey); if(ret){ - kdc_log(0, "no suitable DES key for server"); + kdc_log(context, config, 0, "no suitable DES key for server"); /* XXX */ make_err_reply(context, reply, KDC_NULL_KEY, "no suitable DES key for server"); @@ -268,7 +279,7 @@ do_version4(unsigned char *buf, 0, name, inst, - v4_realm, + config->v4_realm, addr->sin_addr.s_addr, &session, life, @@ -288,7 +299,7 @@ do_version4(unsigned char *buf, &session, sname, sinst, - v4_realm, + config->v4_realm, life, server->kvno % 255, &ticket, @@ -337,22 +348,24 @@ do_version4(unsigned char *buf, RCHECK(krb5_ret_int8(sp, &kvno), out2); RCHECK(krb5_ret_stringz(sp, &realm), out2); - ret = krb5_425_conv_principal(context, "krbtgt", realm, v4_realm, + ret = krb5_425_conv_principal(context, "krbtgt", realm, + config->v4_realm, &tgt_princ); if(ret){ - kdc_log(0, "Converting krbtgt principal (krb4): %s", + kdc_log(context, config, 0, + "Converting krbtgt principal (krb4): %s", krb5_get_err_text(context, ret)); make_err_reply(context, reply, KFAILURE, "Failed to convert v4 principal (krbtgt)"); goto out2; } - ret = db_fetch(tgt_princ, &tgt); + ret = db_fetch(context, config, tgt_princ, &tgt); if(ret){ char *s; - s = kdc_log_msg(0, "Ticket-granting ticket not " + s = kdc_log_msg(context, config, 0, "Ticket-granting ticket not " "found in database (krb4): krbtgt.%s@%s: %s", - realm, v4_realm, + realm, config->v4_realm, krb5_get_err_text(context, ret)); make_err_reply(context, reply, KFAILURE, s); free(s); @@ -360,16 +373,19 @@ do_version4(unsigned char *buf, } if(tgt->kvno % 256 != kvno){ - kdc_log(0, "tgs-req (krb4) with old kvno %d (current %d) for " - "krbtgt.%s@%s", kvno, tgt->kvno % 256, realm, v4_realm); + kdc_log(context, config, 0, + "tgs-req (krb4) with old kvno %d (current %d) for " + "krbtgt.%s@%s", kvno, tgt->kvno % 256, + realm, config->v4_realm); make_err_reply(context, reply, KDC_AUTH_EXP, "old krbtgt kvno used"); goto out2; } - ret = get_des_key(tgt, TRUE, FALSE, &tkey); + ret = get_des_key(context, tgt, TRUE, FALSE, &tkey); if(ret){ - kdc_log(0, "no suitable DES key for krbtgt (krb4)"); + kdc_log(context, config, 0, + "no suitable DES key for krbtgt (krb4)"); /* XXX */ make_err_reply(context, reply, KDC_NULL_KEY, "no suitable DES key for krbtgt"); @@ -384,15 +400,16 @@ do_version4(unsigned char *buf, auth.data = buf; auth.length = pos; - if (check_ticket_addresses) + if (config->check_ticket_addresses) address = addr->sin_addr.s_addr; else address = 0; - ret = _krb5_krb_rd_req(context, &auth, "krbtgt", realm, v4_realm, + ret = _krb5_krb_rd_req(context, &auth, "krbtgt", realm, + config->v4_realm, address, &tkey->key, &ad); if(ret){ - kdc_log(0, "krb_rd_req: %d", ret); + kdc_log(context, config, 0, "krb_rd_req: %d", ret); make_err_reply(context, reply, ret, "failed to parse request"); goto out2; } @@ -405,64 +422,72 @@ do_version4(unsigned char *buf, RCHECK(krb5_ret_stringz(sp, &sinst), out2); snprintf (server_name, sizeof(server_name), "%s.%s@%s", - sname, sinst, v4_realm); + sname, sinst, config->v4_realm); snprintf (client_name, sizeof(client_name), "%s.%s@%s", ad.pname, ad.pinst, ad.prealm); - kdc_log(0, "TGS-REQ (krb4) %s from %s for %s", + kdc_log(context, config, 0, "TGS-REQ (krb4) %s from %s for %s", client_name, from, server_name); if(strcmp(ad.prealm, realm)){ - kdc_log(0, "Can't hop realms (krb4) %s -> %s", realm, ad.prealm); + kdc_log(context, config, 0, + "Can't hop realms (krb4) %s -> %s", realm, ad.prealm); make_err_reply(context, reply, KERB_ERR_PRINCIPAL_UNKNOWN, "Can't hop realms"); goto out2; } - if (!enable_v4_cross_realm && strcmp(realm, v4_realm) != 0) { - kdc_log(0, "krb4 Cross-realm %s -> %s disabled", realm, v4_realm); + if (!config->enable_v4_cross_realm && strcmp(realm, config->v4_realm) != 0) { + kdc_log(context, config, 0, + "krb4 Cross-realm %s -> %s disabled", + realm, config->v4_realm); make_err_reply(context, reply, KERB_ERR_PRINCIPAL_UNKNOWN, "Can't hop realms"); goto out2; } if(strcmp(sname, "changepw") == 0){ - kdc_log(0, "Bad request for changepw ticket (krb4)"); + kdc_log(context, config, 0, + "Bad request for changepw ticket (krb4)"); make_err_reply(context, reply, KERB_ERR_PRINCIPAL_UNKNOWN, "Can't authorize password change based on TGT"); goto out2; } - ret = db_fetch4(ad.pname, ad.pinst, ad.prealm, &client); + ret = db_fetch4(context, config, ad.pname, ad.pinst, ad.prealm, &client); if(ret && ret != HDB_ERR_NOENTRY) { char *s; - s = kdc_log_msg(0, "Client not found in database: (krb4) %s: %s", + s = kdc_log_msg(context, config, 0, + "Client not found in database: (krb4) %s: %s", client_name, krb5_get_err_text(context, ret)); make_err_reply(context, reply, KERB_ERR_PRINCIPAL_UNKNOWN, s); free(s); goto out2; } - if (client == NULL && strcmp(ad.prealm, v4_realm) == 0) { + if (client == NULL && strcmp(ad.prealm, config->v4_realm) == 0) { char *s; - s = kdc_log_msg(0, "Local client not found in database: (krb4) " + s = kdc_log_msg(context, config, 0, + "Local client not found in database: (krb4) " "%s", client_name); make_err_reply(context, reply, KERB_ERR_PRINCIPAL_UNKNOWN, s); free(s); goto out2; } - ret = db_fetch4(sname, sinst, v4_realm, &server); + ret = db_fetch4(context, config, sname, sinst, config->v4_realm, &server); if(ret){ char *s; - s = kdc_log_msg(0, "Server not found in database (krb4): %s: %s", + s = kdc_log_msg(context, config, 0, + "Server not found in database (krb4): %s: %s", server_name, krb5_get_err_text(context, ret)); make_err_reply(context, reply, KERB_ERR_PRINCIPAL_UNKNOWN, s); free(s); goto out2; } - ret = check_flags (client, client_name, + ret = check_flags (context, config, + client, client_name, server, server_name, FALSE); if (ret) { @@ -472,9 +497,10 @@ do_version4(unsigned char *buf, goto out2; } - ret = get_des_key(server, TRUE, FALSE, &skey); + ret = get_des_key(context, server, TRUE, FALSE, &skey); if(ret){ - kdc_log(0, "no suitable DES key for server (krb4)"); + kdc_log(context, config, 0, + "no suitable DES key for server (krb4)"); /* XXX */ make_err_reply(context, reply, KDC_NULL_KEY, "no suitable DES key for server"); @@ -541,7 +567,7 @@ do_version4(unsigned char *buf, &session, sname, sinst, - v4_realm, + config->v4_realm, life, server->kvno % 255, &ticket, @@ -572,13 +598,13 @@ do_version4(unsigned char *buf, if(tgt_princ) krb5_free_principal(context, tgt_princ); if(tgt) - free_ent(tgt); + free_ent(context, tgt); break; } case AUTH_MSG_ERR_REPLY: break; default: - kdc_log(0, "Unknown message type (krb4): %d from %s", + kdc_log(context, config, 0, "Unknown message type (krb4): %d from %s", msg_type, from); make_err_reply(context, reply, KFAILURE, "Unknown message type"); @@ -595,15 +621,17 @@ do_version4(unsigned char *buf, if(sinst) free(sinst); if(client) - free_ent(client); + free_ent(context, client); if(server) - free_ent(server); + free_ent(context, server); krb5_storage_free(sp); return 0; } krb5_error_code -encode_v4_ticket(void *buf, size_t len, const EncTicketPart *et, +encode_v4_ticket(krb5_context context, + struct krb5_kdc_configuration *config, + void *buf, size_t len, const EncTicketPart *et, const PrincipalName *service, size_t *size) { krb5_storage *sp; @@ -690,7 +718,8 @@ encode_v4_ticket(void *buf, size_t len, const EncTicketPart *et, } krb5_error_code -get_des_key(hdb_entry *principal, krb5_boolean is_server, +get_des_key(krb5_context context, + hdb_entry *principal, krb5_boolean is_server, krb5_boolean prefer_afs_key, Key **ret_key) { Key *v5_key = NULL, *v4_key = NULL, *afs_key = NULL, *server_key = NULL; diff --git a/kdc/kerberos5.c b/kdc/kerberos5.c index 736c65755..ecde014d1 100644 --- a/kdc/kerberos5.c +++ b/kdc/kerberos5.c @@ -88,7 +88,8 @@ find_padata(KDC_REQ *req, int *start, int type) */ static krb5_error_code -find_etype(hdb_entry *princ, krb5_enctype *etypes, unsigned len, +find_etype(krb5_context context, hdb_entry *princ, + krb5_enctype *etypes, unsigned len, Key **ret_key, krb5_enctype *ret_etype) { int i; @@ -116,7 +117,9 @@ find_etype(hdb_entry *princ, krb5_enctype *etypes, unsigned len, } static krb5_error_code -find_keys(hdb_entry *client, +find_keys(krb5_context context, + struct krb5_kdc_configuration *config, + hdb_entry *client, hdb_entry *server, Key **ckey, krb5_enctype *cetype, @@ -131,11 +134,12 @@ find_keys(hdb_entry *client, if(client){ /* find client key */ - ret = find_etype(client, etypes, num_etypes, ckey, cetype); + ret = find_etype(context, client, etypes, num_etypes, ckey, cetype); if (ret) { if (krb5_unparse_name(context, client->principal, &name) != 0) name = unparse_name; - kdc_log(0, "Client (%s) has no support for etypes", name); + kdc_log(context, config, 0, + "Client (%s) has no support for etypes", name); if (name != unparse_name) free(name); return ret; @@ -144,11 +148,12 @@ find_keys(hdb_entry *client, if(server){ /* find server key */ - ret = find_etype(server, etypes, num_etypes, skey, setype); + ret = find_etype(context, server, etypes, num_etypes, skey, setype); if (ret) { if (krb5_unparse_name(context, server->principal, &name) != 0) name = unparse_name; - kdc_log(0, "Server (%s) has no support for etypes", name); + kdc_log(context, config, 0, + "Server (%s) has no support for etypes", name); if (name != unparse_name) free(name); return ret; @@ -175,7 +180,9 @@ make_anonymous_principalname (PrincipalName *pn) } static void -log_timestamp(const char *type, +log_timestamp(krb5_context context, + struct krb5_kdc_configuration *config, + const char *type, KerberosTime authtime, KerberosTime *starttime, KerberosTime endtime, KerberosTime *renew_till) { @@ -192,12 +199,15 @@ log_timestamp(const char *type, else strlcpy(rtime, "unset", sizeof(rtime)); - kdc_log(5, "%s authtime: %s starttime: %s endtype: %s renew till: %s", + kdc_log(context, config, 5, + "%s authtime: %s starttime: %s endtype: %s renew till: %s", type, atime, stime, etime, rtime); } static krb5_error_code -encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek, +encode_reply(krb5_context context, + struct krb5_kdc_configuration *config, + KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek, krb5_enctype etype, int skvno, EncryptionKey *skey, int ckvno, EncryptionKey *ckey, @@ -212,13 +222,13 @@ encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek, ASN1_MALLOC_ENCODE(EncTicketPart, buf, buf_size, et, &len, ret); if(ret) { - kdc_log(0, "Failed to encode ticket: %s", + kdc_log(context, config, 0, "Failed to encode ticket: %s", krb5_get_err_text(context, ret)); return ret; } if(buf_size != len) { free(buf); - kdc_log(0, "Internal error in ASN.1 encoder"); + kdc_log(context, config, 0, "Internal error in ASN.1 encoder"); *e_text = "KDC internal error"; return KRB5KRB_ERR_GENERIC; } @@ -226,7 +236,7 @@ encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek, ret = krb5_crypto_init(context, skey, etype, &crypto); if (ret) { free(buf); - kdc_log(0, "krb5_crypto_init failed: %s", + kdc_log(context, config, 0, "krb5_crypto_init failed: %s", krb5_get_err_text(context, ret)); return ret; } @@ -241,30 +251,30 @@ encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek, free(buf); krb5_crypto_destroy(context, crypto); if(ret) { - kdc_log(0, "Failed to encrypt data: %s", + kdc_log(context, config, 0, "Failed to encrypt data: %s", krb5_get_err_text(context, ret)); return ret; } - if(rep->msg_type == krb_as_rep && !encode_as_rep_as_tgs_rep) + if(rep->msg_type == krb_as_rep && !config->encode_as_rep_as_tgs_rep) ASN1_MALLOC_ENCODE(EncASRepPart, buf, buf_size, ek, &len, ret); else ASN1_MALLOC_ENCODE(EncTGSRepPart, buf, buf_size, ek, &len, ret); if(ret) { - kdc_log(0, "Failed to encode KDC-REP: %s", + kdc_log(context, config, 0, "Failed to encode KDC-REP: %s", krb5_get_err_text(context, ret)); return ret; } if(buf_size != len) { free(buf); - kdc_log(0, "Internal error in ASN.1 encoder"); + kdc_log(context, config, 0, "Internal error in ASN.1 encoder"); *e_text = "KDC internal error"; return KRB5KRB_ERR_GENERIC; } ret = krb5_crypto_init(context, ckey, 0, &crypto); if (ret) { free(buf); - kdc_log(0, "krb5_crypto_init failed: %s", + kdc_log(context, config, 0, "krb5_crypto_init failed: %s", krb5_get_err_text(context, ret)); return ret; } @@ -291,13 +301,13 @@ encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek, } krb5_crypto_destroy(context, crypto); if(ret) { - kdc_log(0, "Failed to encode KDC-REP: %s", + kdc_log(context, config, 0, "Failed to encode KDC-REP: %s", krb5_get_err_text(context, ret)); return ret; } if(buf_size != len) { free(buf); - kdc_log(0, "Internal error in ASN.1 encoder"); + kdc_log(context, config, 0, "Internal error in ASN.1 encoder"); *e_text = "KDC internal error"; return KRB5KRB_ERR_GENERIC; } @@ -307,7 +317,7 @@ encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek, } static krb5_error_code -make_etype_info_entry(ETYPE_INFO_ENTRY *ent, Key *key) +make_etype_info_entry(krb5_context context, ETYPE_INFO_ENTRY *ent, Key *key) { ent->etype = key->key.keytype; if(key->salt){ @@ -318,7 +328,7 @@ make_etype_info_entry(ETYPE_INFO_ENTRY *ent, Key *key) else if(key->salt->type == hdb_afs3_salt) *ent->salttype = 2; else { - kdc_log(0, "unknown salt-type: %d", + kdc_log(context, config, 0, "unknown salt-type: %d", key->salt->type); return KRB5KRB_ERR_GENERIC; } @@ -345,7 +355,9 @@ make_etype_info_entry(ETYPE_INFO_ENTRY *ent, Key *key) } static krb5_error_code -get_pa_etype_info(METHOD_DATA *md, hdb_entry *client, +get_pa_etype_info(krb5_context context, + struct krb5_kdc_configuration *config, + METHOD_DATA *md, hdb_entry *client, ENCTYPE *etypes, unsigned int etypes_len) { krb5_error_code ret = 0; @@ -372,7 +384,8 @@ get_pa_etype_info(METHOD_DATA *md, hdb_entry *client, if(client->keys.val[i].key.keytype == etypes[j]) { if (krb5_enctype_valid(context, etypes[j]) != 0) continue; - if((ret = make_etype_info_entry(&pa.val[n++], + if((ret = make_etype_info_entry(context, + &pa.val[n++], &client->keys.val[i])) != 0) { free_ETYPE_INFO(&pa); return ret; @@ -388,7 +401,8 @@ get_pa_etype_info(METHOD_DATA *md, hdb_entry *client, } if (krb5_enctype_valid(context, client->keys.val[i].key.keytype) != 0) continue; - if((ret = make_etype_info_entry(&pa.val[n++], + if((ret = make_etype_info_entry(context, + &pa.val[n++], &client->keys.val[i])) != 0) { free_ETYPE_INFO(&pa); return ret; @@ -401,7 +415,7 @@ get_pa_etype_info(METHOD_DATA *md, hdb_entry *client, ret = krb5_unparse_name(context, client->principal, &name); if (ret) name = ""; - kdc_log(0, "internal error in get_pa_etype_info(%s): %d != %d", + kdc_log(context, config, 0, "internal error in get_pa_etype_info(%s): %d != %d", name, n, pa.len); if (ret == 0) free(name); @@ -504,7 +518,9 @@ only_older_enctype_p(const KDC_REQ *req) */ static krb5_error_code -get_pa_etype_info2(METHOD_DATA *md, hdb_entry *client, +get_pa_etype_info2(krb5_context context, + struct krb5_kdc_configuration *config, + METHOD_DATA *md, hdb_entry *client, ENCTYPE *etypes, unsigned int etypes_len) { krb5_error_code ret = 0; @@ -559,7 +575,7 @@ get_pa_etype_info2(METHOD_DATA *md, hdb_entry *client, ret = krb5_unparse_name(context, client->principal, &name); if (ret) name = ""; - kdc_log(0, "internal error in get_pa_etype_info2(%s): %d != %d", + kdc_log(context, config, 0, "internal error in get_pa_etype_info2(%s): %d != %d", name, n, pa.len); if (ret == 0) free(name); @@ -588,36 +604,38 @@ get_pa_etype_info2(METHOD_DATA *md, hdb_entry *client, */ krb5_error_code -check_flags(hdb_entry *client, const char *client_name, +check_flags(krb5_context context, + struct krb5_kdc_configuration *config, + hdb_entry *client, const char *client_name, hdb_entry *server, const char *server_name, krb5_boolean is_as_req) { if(client != NULL) { /* check client */ if (client->flags.invalid) { - kdc_log(0, "Client (%s) has invalid bit set", client_name); + kdc_log(context, config, 0, "Client (%s) has invalid bit set", client_name); return KRB5KDC_ERR_POLICY; } if(!client->flags.client){ - kdc_log(0, "Principal may not act as client -- %s", + kdc_log(context, config, 0, "Principal may not act as client -- %s", client_name); return KRB5KDC_ERR_POLICY; } if (client->valid_start && *client->valid_start > kdc_time) { - kdc_log(0, "Client not yet valid -- %s", client_name); + kdc_log(context, config, 0, "Client not yet valid -- %s", client_name); return KRB5KDC_ERR_CLIENT_NOTYET; } if (client->valid_end && *client->valid_end < kdc_time) { - kdc_log(0, "Client expired -- %s", client_name); + kdc_log(context, config, 0, "Client expired -- %s", client_name); return KRB5KDC_ERR_NAME_EXP; } if (client->pw_end && *client->pw_end < kdc_time && !server->flags.change_pw) { - kdc_log(0, "Client's key has expired -- %s", client_name); + kdc_log(context, config, 0, "Client's key has expired -- %s", client_name); return KRB5KDC_ERR_KEY_EXPIRED; } } @@ -626,33 +644,33 @@ check_flags(hdb_entry *client, const char *client_name, if (server != NULL) { if (server->flags.invalid) { - kdc_log(0, "Server has invalid flag set -- %s", server_name); + kdc_log(context, config, 0, "Server has invalid flag set -- %s", server_name); return KRB5KDC_ERR_POLICY; } if(!server->flags.server){ - kdc_log(0, "Principal may not act as server -- %s", + kdc_log(context, config, 0, "Principal may not act as server -- %s", server_name); return KRB5KDC_ERR_POLICY; } if(!is_as_req && server->flags.initial) { - kdc_log(0, "AS-REQ is required for server -- %s", server_name); + kdc_log(context, config, 0, "AS-REQ is required for server -- %s", server_name); return KRB5KDC_ERR_POLICY; } if (server->valid_start && *server->valid_start > kdc_time) { - kdc_log(0, "Server not yet valid -- %s", server_name); + kdc_log(context, config, 0, "Server not yet valid -- %s", server_name); return KRB5KDC_ERR_SERVICE_NOTYET; } if (server->valid_end && *server->valid_end < kdc_time) { - kdc_log(0, "Server expired -- %s", server_name); + kdc_log(context, config, 0, "Server expired -- %s", server_name); return KRB5KDC_ERR_SERVICE_EXP; } if (server->pw_end && *server->pw_end < kdc_time) { - kdc_log(0, "Server's key has expired -- %s", server_name); + kdc_log(context, config, 0, "Server's key has expired -- %s", server_name); return KRB5KDC_ERR_KEY_EXPIRED; } } @@ -666,17 +684,19 @@ check_flags(hdb_entry *client, const char *client_name, */ static krb5_boolean -check_addresses(HostAddresses *addresses, const struct sockaddr *from) +check_addresses(krb5_context context, + struct krb5_kdc_configuration *config, + HostAddresses *addresses, const struct sockaddr *from) { krb5_error_code ret; krb5_address addr; krb5_boolean result; - if(check_ticket_addresses == 0) + if(config->check_ticket_addresses == 0) return TRUE; if(addresses == NULL) - return allow_null_ticket_addresses; + return config->allow_null_ticket_addresses; ret = krb5_sockaddr2address (context, from, &addr); if(ret) @@ -688,7 +708,9 @@ check_addresses(HostAddresses *addresses, const struct sockaddr *from) } krb5_error_code -as_rep(KDC_REQ *req, +as_rep(krb5_context context, + struct krb5_kdc_configuration *config, + KDC_REQ *req, krb5_data *reply, const char *from, struct sockaddr *from_addr) @@ -722,7 +744,7 @@ as_rep(KDC_REQ *req, ret = krb5_unparse_name(context, server_princ, &server_name); } if (ret) { - kdc_log(0, "AS-REQ malformed server name from %s", from); + kdc_log(context, config, 0, "AS-REQ malformed server name from %s", from); goto out; } @@ -735,30 +757,31 @@ as_rep(KDC_REQ *req, ret = krb5_unparse_name(context, client_princ, &client_name); } if (ret) { - kdc_log(0, "AS-REQ malformed client name from %s", from); + kdc_log(context, config, 0, "AS-REQ malformed client name from %s", from); goto out; } - kdc_log(0, "AS-REQ %s from %s for %s", + kdc_log(context, config, 0, "AS-REQ %s from %s for %s", client_name, from, server_name); - ret = db_fetch(client_princ, &client); + ret = db_fetch(context, config, client_princ, &client); if(ret){ - kdc_log(0, "UNKNOWN -- %s: %s", client_name, + kdc_log(context, config, 0, "UNKNOWN -- %s: %s", client_name, krb5_get_err_text(context, ret)); ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; goto out; } - ret = db_fetch(server_princ, &server); + ret = db_fetch(context, config, server_princ, &server); if(ret){ - kdc_log(0, "UNKNOWN -- %s: %s", server_name, + kdc_log(context, config, 0, "UNKNOWN -- %s: %s", server_name, krb5_get_err_text(context, ret)); ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; goto out; } - ret = check_flags(client, client_name, server, server_name, TRUE); + ret = check_flags(context, config, + client, client_name, server, server_name, TRUE); if(ret) goto out; @@ -771,7 +794,8 @@ as_rep(KDC_REQ *req, int found_pa = 0; #ifdef PKINIT - kdc_log(5, "Looking for PKINIT pa-data -- %s", client_name); + kdc_log(context, config, 5, + "Looking for PKINIT pa-data -- %s", client_name); e_text = "No PKINIT PA found"; @@ -794,7 +818,7 @@ as_rep(KDC_REQ *req, ret = pk_rd_padata(context, req, pa, &pkp); if (ret) { ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; - kdc_log(5, "Failed to decode PKINIT PA-DATA -- %s", + kdc_log(context, config, 5, "Failed to decode PKINIT PA-DATA -- %s", client_name); goto ts_enc; } @@ -815,7 +839,8 @@ as_rep(KDC_REQ *req, } found_pa = 1; et.flags.pre_authent = 1; - kdc_log(2, "PKINIT pre-authentication succeeded -- %s using %s", + kdc_log(context, config, 2, + "PKINIT pre-authentication succeeded -- %s using %s", client_name, client_cert); free(client_cert); if (pkp) @@ -823,7 +848,8 @@ as_rep(KDC_REQ *req, } ts_enc: #endif - kdc_log(5, "Looking for ENC-TS pa-data -- %s", client_name); + kdc_log(context, config, 5, "Looking for ENC-TS pa-data -- %s", + client_name); i = 0; e_text = "No ENC-TS found"; @@ -842,7 +868,7 @@ as_rep(KDC_REQ *req, &len); if (ret) { ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; - kdc_log(5, "Failed to decode PA-DATA -- %s", + kdc_log(context, config, 5, "Failed to decode PA-DATA -- %s", client_name); goto out; } @@ -855,10 +881,12 @@ as_rep(KDC_REQ *req, if(krb5_enctype_to_string(context, enc_data.etype, &estr)) estr = NULL; if(estr == NULL) - kdc_log(5, "No client key matching pa-data (%d) -- %s", + kdc_log(context, config, 5, + "No client key matching pa-data (%d) -- %s", enc_data.etype, client_name); else - kdc_log(5, "No client key matching pa-data (%s) -- %s", + kdc_log(context, config, 5, + "No client key matching pa-data (%s) -- %s", estr, client_name); free(estr); @@ -869,7 +897,7 @@ as_rep(KDC_REQ *req, try_next_key: ret = krb5_crypto_init(context, &pa_key->key, 0, &crypto); if (ret) { - kdc_log(0, "krb5_crypto_init failed: %s", + kdc_log(context, config, 0, "krb5_crypto_init failed: %s", krb5_get_err_text(context, ret)); free_EncryptedData(&enc_data); continue; @@ -887,7 +915,8 @@ as_rep(KDC_REQ *req, goto try_next_key; free_EncryptedData(&enc_data); e_text = "Failed to decrypt PA-DATA"; - kdc_log (5, "Failed to decrypt PA-DATA -- %s", + kdc_log(context, config, + 5, "Failed to decrypt PA-DATA -- %s", client_name); ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; continue; @@ -901,7 +930,8 @@ as_rep(KDC_REQ *req, if(ret){ e_text = "Failed to decode PA-ENC-TS-ENC"; ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; - kdc_log (5, "Failed to decode PA-ENC-TS_ENC -- %s", + kdc_log(context, config, + 5, "Failed to decode PA-ENC-TS_ENC -- %s", client_name); continue; } @@ -909,27 +939,29 @@ as_rep(KDC_REQ *req, if (abs(kdc_time - p.patimestamp) > context->max_skew) { ret = KRB5KDC_ERR_PREAUTH_FAILED; e_text = "Too large time skew"; - kdc_log(0, "Too large time skew -- %s", client_name); + kdc_log(context, config, 0, + "Too large time skew -- %s", client_name); goto out; } et.flags.pre_authent = 1; - kdc_log(2, "ENC-TS Pre-authentication succeeded -- %s", + kdc_log(context, config, 2, + "ENC-TS Pre-authentication succeeded -- %s", client_name); break; } #ifdef PKINIT preauth_done: #endif - if(found_pa == 0 && require_preauth) + if(found_pa == 0 && config->require_preauth) goto use_pa; /* We come here if we found a pa-enc-timestamp, but if there was some problem with it, other than too large skew */ if(found_pa && et.flags.pre_authent == 0){ - kdc_log(0, "%s -- %s", e_text, client_name); + kdc_log(context, config, 0, "%s -- %s", e_text, client_name); e_text = NULL; goto out; } - }else if (require_preauth + }else if (config->require_preauth || client->flags.require_preauth || server->flags.require_preauth) { METHOD_DATA method_data; @@ -964,10 +996,10 @@ as_rep(KDC_REQ *req, /* XXX check ret */ if (only_older_enctype_p(req)) - ret = get_pa_etype_info(&method_data, client, + ret = get_pa_etype_info(context, config, &method_data, client, b->etype.val, b->etype.len); /* XXX check ret */ - ret = get_pa_etype_info2(&method_data, client, + ret = get_pa_etype_info2(context, config, &method_data, client, b->etype.val, b->etype.len); @@ -987,16 +1019,18 @@ as_rep(KDC_REQ *req, NULL, reply); free(buf); - kdc_log(0, "No preauth found, returning PREAUTH-REQUIRED -- %s", + kdc_log(context, config, 0, + "No preauth found, returning PREAUTH-REQUIRED -- %s", client_name); ret = 0; goto out2; } - ret = find_keys(client, server, &ckey, &cetype, &skey, &setype, + ret = find_keys(context, config, + client, server, &ckey, &cetype, &skey, &setype, b->etype.val, b->etype.len); if(ret) { - kdc_log(0, "Server/client has no support for etypes"); + kdc_log(context, config, 0, "Server/client has no support for etypes"); goto out; } @@ -1015,12 +1049,12 @@ as_rep(KDC_REQ *req, if (p && i + 1 < b->etype.len) p = rk_strpoolprintf(p, ", "); if (p == NULL) { - kdc_log(0, "out of meory"); + kdc_log(context, config, 0, "out of meory"); goto out; } } str = rk_strpoolcollect(p); - kdc_log(0, "Client supported enctypes: %s", str); + kdc_log(context, config, 0, "Client supported enctypes: %s", str); free(str); } { @@ -1031,13 +1065,13 @@ as_rep(KDC_REQ *req, if(ret == 0) { ret = krb5_enctype_to_string(context, setype, &set); if (ret == 0) { - kdc_log(5, "Using %s/%s", cet, set); + kdc_log(context, config, 5, "Using %s/%s", cet, set); free(set); } free(cet); } if (ret != 0) - kdc_log(5, "Using e-types %d/%d", cetype, setype); + kdc_log(context, config, 5, "Using e-types %d/%d", cetype, setype); } { @@ -1045,61 +1079,67 @@ as_rep(KDC_REQ *req, unparse_flags(KDCOptions2int(f), asn1_KDCOptions_units(), str, sizeof(str)); if(*str) - kdc_log(2, "Requested flags: %s", str); + kdc_log(context, config, 2, "Requested flags: %s", str); } if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey - || (f.request_anonymous && !allow_anonymous)) { + || (f.request_anonymous && !config->allow_anonymous)) { ret = KRB5KDC_ERR_BADOPTION; - kdc_log(0, "Bad KDC options -- %s", client_name); + kdc_log(context, config, 0, "Bad KDC options -- %s", client_name); goto out; } rep.pvno = 5; rep.msg_type = krb_as_rep; - copy_Realm(&b->realm, &rep.crealm); + copy_Realm(&client->principal->realm, &rep.crealm); if (f.request_anonymous) make_anonymous_principalname (&rep.cname); else - copy_PrincipalName(b->cname, &rep.cname); + _krb5_principal2principalname(&rep.cname, + client->principal); rep.ticket.tkt_vno = 5; - copy_Realm(&b->realm, &rep.ticket.realm); - copy_PrincipalName(b->sname, &rep.ticket.sname); + copy_Realm(&server->principal->realm, &rep.ticket.realm); + _krb5_principal2principalname(&rep.ticket.sname, + server->principal); et.flags.initial = 1; if(client->flags.forwardable && server->flags.forwardable) et.flags.forwardable = f.forwardable; else if (f.forwardable) { ret = KRB5KDC_ERR_POLICY; - kdc_log(0, "Ticket may not be forwardable -- %s", client_name); + kdc_log(context, config, 0, + "Ticket may not be forwardable -- %s", client_name); goto out; } if(client->flags.proxiable && server->flags.proxiable) et.flags.proxiable = f.proxiable; else if (f.proxiable) { ret = KRB5KDC_ERR_POLICY; - kdc_log(0, "Ticket may not be proxiable -- %s", client_name); + kdc_log(context, config, 0, + "Ticket may not be proxiable -- %s", client_name); goto out; } if(client->flags.postdate && server->flags.postdate) et.flags.may_postdate = f.allow_postdate; else if (f.allow_postdate){ ret = KRB5KDC_ERR_POLICY; - kdc_log(0, "Ticket may not be postdatable -- %s", client_name); + kdc_log(context, config, 0, + "Ticket may not be postdatable -- %s", client_name); goto out; } /* check for valid set of addresses */ - if(!check_addresses(b->addresses, from_addr)) { + if(!check_addresses(context, config, b->addresses, from_addr)) { ret = KRB5KRB_AP_ERR_BADADDR; - kdc_log(0, "Bad address list requested -- %s", client_name); + kdc_log(context, config, 0, + "Bad address list requested -- %s", client_name); goto out; } krb5_generate_random_keyblock(context, setype, &et.key); copy_PrincipalName(&rep.cname, &et.cname); - copy_Realm(&b->realm, &et.crealm); + copy_Realm(&rep.crealm, &et.crealm); { time_t start; @@ -1177,8 +1217,8 @@ as_rep(KDC_REQ *req, ek.last_req.val = malloc(2 * sizeof(*ek.last_req.val)); ek.last_req.len = 0; if (client->pw_end - && (kdc_warn_pwexpire == 0 - || kdc_time + kdc_warn_pwexpire <= *client->pw_end)) { + && (config->kdc_warn_pwexpire == 0 + || kdc_time + config->kdc_warn_pwexpire <= *client->pw_end)) { ek.last_req.val[ek.last_req.len].lr_type = LR_PW_EXPTIME; ek.last_req.val[ek.last_req.len].lr_value = *client->pw_end; ++ek.last_req.len; @@ -1244,10 +1284,11 @@ as_rep(KDC_REQ *req, rep.padata = NULL; } - log_timestamp("AS-REQ", et.authtime, et.starttime, + log_timestamp(context, config, "AS-REQ", et.authtime, et.starttime, et.endtime, et.renew_till); - ret = encode_reply(&rep, &et, &ek, setype, server->kvno, &skey->key, + ret = encode_reply(context, config, + &rep, &et, &ek, setype, server->kvno, &skey->key, client->kvno, reply_key, &e_text, reply); free_EncTicketPart(&et); free_EncKDCRepPart(&ek); @@ -1277,44 +1318,46 @@ as_rep(KDC_REQ *req, krb5_free_principal(context, server_princ); free(server_name); if(client) - free_ent(client); + free_ent(context, client); if(server) - free_ent(server); + free_ent(context, server); return ret; } static krb5_error_code -check_tgs_flags(KDC_REQ_BODY *b, EncTicketPart *tgt, EncTicketPart *et) +check_tgs_flags(krb5_context context, + struct krb5_kdc_configuration *config, + KDC_REQ_BODY *b, EncTicketPart *tgt, EncTicketPart *et) { KDCOptions f = b->kdc_options; if(f.validate){ if(!tgt->flags.invalid || tgt->starttime == NULL){ - kdc_log(0, "Bad request to validate ticket"); + kdc_log(context, config, 0, "Bad request to validate ticket"); return KRB5KDC_ERR_BADOPTION; } if(*tgt->starttime > kdc_time){ - kdc_log(0, "Early request to validate ticket"); + kdc_log(context, config, 0, "Early request to validate ticket"); return KRB5KRB_AP_ERR_TKT_NYV; } /* XXX tkt = tgt */ et->flags.invalid = 0; }else if(tgt->flags.invalid){ - kdc_log(0, "Ticket-granting ticket has INVALID flag set"); + kdc_log(context, config, 0, "Ticket-granting ticket has INVALID flag set"); return KRB5KRB_AP_ERR_TKT_INVALID; } if(f.forwardable){ if(!tgt->flags.forwardable){ - kdc_log(0, "Bad request for forwardable ticket"); + kdc_log(context, config, 0, "Bad request for forwardable ticket"); return KRB5KDC_ERR_BADOPTION; } et->flags.forwardable = 1; } if(f.forwarded){ if(!tgt->flags.forwardable){ - kdc_log(0, "Request to forward non-forwardable ticket"); + kdc_log(context, config, 0, "Request to forward non-forwardable ticket"); return KRB5KDC_ERR_BADOPTION; } et->flags.forwarded = 1; @@ -1325,14 +1368,16 @@ check_tgs_flags(KDC_REQ_BODY *b, EncTicketPart *tgt, EncTicketPart *et) if(f.proxiable){ if(!tgt->flags.proxiable){ - kdc_log(0, "Bad request for proxiable ticket"); + kdc_log(context, config, 0, + "Bad request for proxiable ticket"); return KRB5KDC_ERR_BADOPTION; } et->flags.proxiable = 1; } if(f.proxy){ if(!tgt->flags.proxiable){ - kdc_log(0, "Request to proxy non-proxiable ticket"); + kdc_log(context, config, 0, + "Request to proxy non-proxiable ticket"); return KRB5KDC_ERR_BADOPTION; } et->flags.proxy = 1; @@ -1343,14 +1388,16 @@ check_tgs_flags(KDC_REQ_BODY *b, EncTicketPart *tgt, EncTicketPart *et) if(f.allow_postdate){ if(!tgt->flags.may_postdate){ - kdc_log(0, "Bad request for post-datable ticket"); + kdc_log(context, config, 0, + "Bad request for post-datable ticket"); return KRB5KDC_ERR_BADOPTION; } et->flags.may_postdate = 1; } if(f.postdated){ if(!tgt->flags.may_postdate){ - kdc_log(0, "Bad request for postdated ticket"); + kdc_log(context, config, 0, + "Bad request for postdated ticket"); return KRB5KDC_ERR_BADOPTION; } if(b->from) @@ -1358,13 +1405,14 @@ check_tgs_flags(KDC_REQ_BODY *b, EncTicketPart *tgt, EncTicketPart *et) et->flags.postdated = 1; et->flags.invalid = 1; }else if(b->from && *b->from > kdc_time + context->max_skew){ - kdc_log(0, "Ticket cannot be postdated"); + kdc_log(context, config, 0, "Ticket cannot be postdated"); return KRB5KDC_ERR_CANNOT_POSTDATE; } if(f.renewable){ if(!tgt->flags.renewable){ - kdc_log(0, "Bad request for renewable ticket"); + kdc_log(context, config, 0, + "Bad request for renewable ticket"); return KRB5KDC_ERR_BADOPTION; } et->flags.renewable = 1; @@ -1375,7 +1423,8 @@ check_tgs_flags(KDC_REQ_BODY *b, EncTicketPart *tgt, EncTicketPart *et) if(f.renew){ time_t old_life; if(!tgt->flags.renewable || tgt->renew_till == NULL){ - kdc_log(0, "Request to renew non-renewable ticket"); + kdc_log(context, config, 0, + "Request to renew non-renewable ticket"); return KRB5KDC_ERR_BADOPTION; } old_life = tgt->endtime; @@ -1389,15 +1438,18 @@ check_tgs_flags(KDC_REQ_BODY *b, EncTicketPart *tgt, EncTicketPart *et) } /* checks for excess flags */ - if(f.request_anonymous && !allow_anonymous){ - kdc_log(0, "Request for anonymous ticket"); + if(f.request_anonymous && !config->allow_anonymous){ + kdc_log(context, config, 0, + "Request for anonymous ticket"); return KRB5KDC_ERR_BADOPTION; } return 0; } static krb5_error_code -fix_transited_encoding(krb5_boolean check_policy, +fix_transited_encoding(krb5_context context, + struct krb5_kdc_configuration *config, + krb5_boolean check_policy, TransitedEncoding *tr, EncTicketPart *et, const char *client_realm, @@ -1410,7 +1462,8 @@ fix_transited_encoding(krb5_boolean check_policy, int i; if(tr->tr_type != DOMAIN_X500_COMPRESS) { - kdc_log(0, "Unknown transited type: %u", tr->tr_type); + kdc_log(context, config, 0, + "Unknown transited type: %u", tr->tr_type); return KRB5KDC_ERR_TRTYPE_NOSUPP; } @@ -1421,7 +1474,8 @@ fix_transited_encoding(krb5_boolean check_policy, client_realm, server_realm); if(ret){ - krb5_warn(context, ret, "Decoding transited encoding"); + krb5_warn(context, ret, + "Decoding transited encoding"); return ret; } if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)) { @@ -1445,7 +1499,8 @@ fix_transited_encoding(krb5_boolean check_policy, } if(num_realms == 0) { if(strcmp(client_realm, server_realm)) - kdc_log(0, "cross-realm %s -> %s", client_realm, server_realm); + kdc_log(context, config, 0, + "cross-realm %s -> %s", client_realm, server_realm); } else { size_t l = 0; char *rs; @@ -1459,7 +1514,9 @@ fix_transited_encoding(krb5_boolean check_policy, strlcat(rs, ", ", l); strlcat(rs, realms[i], l); } - kdc_log(0, "cross-realm %s -> %s via [%s]", client_realm, server_realm, rs); + kdc_log(context, config, 0, + "cross-realm %s -> %s via [%s]", + client_realm, server_realm, rs); free(rs); } } @@ -1487,7 +1544,9 @@ fix_transited_encoding(krb5_boolean check_policy, static krb5_error_code -tgs_make_reply(KDC_REQ_BODY *b, +tgs_make_reply(krb5_context context, + struct krb5_kdc_configuration *config, + KDC_REQ_BODY *b, EncTicketPart *tgt, EncTicketPart *adtkt, AuthorizationData *auth_data, @@ -1523,10 +1582,11 @@ tgs_make_reply(KDC_REQ_BODY *b, return KRB5KDC_ERR_ETYPE_NOSUPP; etype = b->etype.val[i]; }else{ - ret = find_keys(NULL, server, NULL, NULL, &skey, &etype, + ret = find_keys(context, config, + NULL, server, NULL, NULL, &skey, &etype, b->etype.val, b->etype.len); if(ret) { - kdc_log(0, "Server has no support for etypes"); + kdc_log(context, config, 0, "Server has no support for etypes"); return ret; } ekey = &skey->key; @@ -1545,7 +1605,7 @@ tgs_make_reply(KDC_REQ_BODY *b, ALLOC(et.starttime); *et.starttime = kdc_time; - ret = check_tgs_flags(b, tgt, &et); + ret = check_tgs_flags(context, config, b, tgt, &et); if(ret) goto out; @@ -1557,14 +1617,19 @@ tgs_make_reply(KDC_REQ_BODY *b, 5) we don't globally allow this */ -#define GLOBAL_FORCE_TRANSITED_CHECK (trpolicy == TRPOLICY_ALWAYS_CHECK) -#define GLOBAL_ALLOW_PER_PRINCIPAL (trpolicy == TRPOLICY_ALLOW_PER_PRINCIPAL) -#define GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK (trpolicy == TRPOLICY_ALWAYS_HONOUR_REQUEST) +#define GLOBAL_FORCE_TRANSITED_CHECK \ + (config->trpolicy == TRPOLICY_ALWAYS_CHECK) +#define GLOBAL_ALLOW_PER_PRINCIPAL \ + (config->trpolicy == TRPOLICY_ALLOW_PER_PRINCIPAL) +#define GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK \ + (config->trpolicy == TRPOLICY_ALWAYS_HONOUR_REQUEST) + /* these will consult the database in future release */ #define PRINCIPAL_FORCE_TRANSITED_CHECK(P) 0 #define PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(P) 0 - ret = fix_transited_encoding(!f.disable_transited_check || + ret = fix_transited_encoding(context, config, + !f.disable_transited_check || GLOBAL_FORCE_TRANSITED_CHECK || PRINCIPAL_FORCE_TRANSITED_CHECK(server) || !((GLOBAL_ALLOW_PER_PRINCIPAL && @@ -1659,7 +1724,7 @@ tgs_make_reply(KDC_REQ_BODY *b, ek.srealm = rep.ticket.realm; ek.sname = rep.ticket.sname; - log_timestamp("TGS-REQ", et.authtime, et.starttime, + log_timestamp(context, config, "TGS-REQ", et.authtime, et.starttime, et.endtime, et.renew_till); /* It is somewhat unclear where the etype in the following @@ -1672,7 +1737,8 @@ tgs_make_reply(KDC_REQ_BODY *b, CAST session key. Should the DES3 etype be added to the etype list, even if we don't want a session key with DES3? */ - ret = encode_reply(&rep, &et, &ek, etype, adtkt ? 0 : server->kvno, ekey, + ret = encode_reply(context, config, + &rep, &et, &ek, etype, adtkt ? 0 : server->kvno, ekey, 0, &tgt->key, e_text, reply); out: free_TGS_REP(&rep); @@ -1688,7 +1754,9 @@ tgs_make_reply(KDC_REQ_BODY *b, } static krb5_error_code -tgs_check_authenticator(krb5_auth_context ac, +tgs_check_authenticator(krb5_context context, + struct krb5_kdc_configuration *config, + krb5_auth_context ac, KDC_REQ_BODY *b, const char **e_text, krb5_keyblock *key) @@ -1702,7 +1770,7 @@ tgs_check_authenticator(krb5_auth_context ac, krb5_auth_con_getauthenticator(context, ac, &auth); if(auth->cksum == NULL){ - kdc_log(0, "No authenticator in request"); + kdc_log(context, config, 0, "No authenticator in request"); ret = KRB5KRB_AP_ERR_INAPP_CKSUM; goto out; } @@ -1716,7 +1784,7 @@ tgs_check_authenticator(krb5_auth_context ac, || #endif !krb5_checksum_is_collision_proof(context, auth->cksum->cksumtype)) { - kdc_log(0, "Bad checksum type in authenticator: %d", + kdc_log(context, config, 0, "Bad checksum type in authenticator: %d", auth->cksum->cksumtype); ret = KRB5KRB_AP_ERR_INAPP_CKSUM; goto out; @@ -1725,13 +1793,13 @@ tgs_check_authenticator(krb5_auth_context ac, /* XXX should not re-encode this */ ASN1_MALLOC_ENCODE(KDC_REQ_BODY, buf, buf_size, b, &len, ret); if(ret){ - kdc_log(0, "Failed to encode KDC-REQ-BODY: %s", + kdc_log(context, config, 0, "Failed to encode KDC-REQ-BODY: %s", krb5_get_err_text(context, ret)); goto out; } if(buf_size != len) { free(buf); - kdc_log(0, "Internal error in ASN.1 encoder"); + kdc_log(context, config, 0, "Internal error in ASN.1 encoder"); *e_text = "KDC internal error"; ret = KRB5KRB_ERR_GENERIC; goto out; @@ -1739,7 +1807,7 @@ tgs_check_authenticator(krb5_auth_context ac, ret = krb5_crypto_init(context, key, 0, &crypto); if (ret) { free(buf); - kdc_log(0, "krb5_crypto_init failed: %s", + kdc_log(context, config, 0, "krb5_crypto_init failed: %s", krb5_get_err_text(context, ret)); goto out; } @@ -1752,7 +1820,7 @@ tgs_check_authenticator(krb5_auth_context ac, free(buf); krb5_crypto_destroy(context, crypto); if(ret){ - kdc_log(0, "Failed to verify checksum: %s", + kdc_log(context, config, 0, "Failed to verify checksum: %s", krb5_get_err_text(context, ret)); } out: @@ -1776,7 +1844,7 @@ get_krbtgt_realm(const PrincipalName *p) } static const char * -find_rpath(Realm crealm, Realm srealm) +find_rpath(krb5_context context, Realm crealm, Realm srealm) { const char *new_realm = krb5_config_get_string(context, NULL, @@ -1789,7 +1857,7 @@ find_rpath(Realm crealm, Realm srealm) static krb5_boolean -need_referral(krb5_principal server, krb5_realm **realms) +need_referral(krb5_context context, krb5_principal server, krb5_realm **realms) { if(server->name.name_type != KRB5_NT_SRV_INST || server->name.name_string.len != 2) @@ -1800,7 +1868,9 @@ need_referral(krb5_principal server, krb5_realm **realms) } static krb5_error_code -tgs_rep2(KDC_REQ_BODY *b, +tgs_rep2(krb5_context context, + struct krb5_kdc_configuration *config, + KDC_REQ_BODY *b, PA_DATA *tgs_req, krb5_data *reply, const char *from, @@ -1832,14 +1902,14 @@ tgs_rep2(KDC_REQ_BODY *b, memset(&ap_req, 0, sizeof(ap_req)); ret = krb5_decode_ap_req(context, &tgs_req->padata_value, &ap_req); if(ret){ - kdc_log(0, "Failed to decode AP-REQ: %s", + kdc_log(context, config, 0, "Failed to decode AP-REQ: %s", krb5_get_err_text(context, ret)); goto out2; } if(!get_krbtgt_realm(&ap_req.ticket.sname)){ /* XXX check for ticket.sname == req.sname */ - kdc_log(0, "PA-DATA is not a ticket-granting ticket"); + kdc_log(context, config, 0, "PA-DATA is not a ticket-granting ticket"); ret = KRB5KDC_ERR_POLICY; /* ? */ goto out2; } @@ -1848,7 +1918,7 @@ tgs_rep2(KDC_REQ_BODY *b, ap_req.ticket.sname, ap_req.ticket.realm); - ret = db_fetch(princ, &krbtgt); + ret = db_fetch(context, config, princ, &krbtgt); if(ret) { char *p; @@ -1856,7 +1926,8 @@ tgs_rep2(KDC_REQ_BODY *b, if (ret != 0) p = ""; krb5_free_principal(context, princ); - kdc_log(0, "Ticket-granting ticket not found in database: %s: %s", + kdc_log(context, config, 0, + "Ticket-granting ticket not found in database: %s: %s", p, krb5_get_err_text(context, ret)); if (ret == 0) free(p); @@ -1872,7 +1943,8 @@ tgs_rep2(KDC_REQ_BODY *b, krb5_free_principal(context, princ); if (ret != 0) p = ""; - kdc_log(0, "Ticket kvno = %d, DB kvno = %d (%s)", + kdc_log(context, config, 0, + "Ticket kvno = %d, DB kvno = %d (%s)", *ap_req.ticket.enc_part.kvno, krbtgt->kvno, p); @@ -1886,7 +1958,8 @@ tgs_rep2(KDC_REQ_BODY *b, if(ret){ char *str; krb5_enctype_to_string(context, ap_req.ticket.enc_part.etype, &str); - kdc_log(0, "No server key found for %s", str); + kdc_log(context, config, 0, + "No server key found for %s", str); free(str); ret = KRB5KRB_AP_ERR_BADKEYVER; goto out2; @@ -1909,7 +1982,7 @@ tgs_rep2(KDC_REQ_BODY *b, krb5_free_principal(context, princ); if(ret) { - kdc_log(0, "Failed to verify AP-REQ: %s", + kdc_log(context, config, 0, "Failed to verify AP-REQ: %s", krb5_get_err_text(context, ret)); goto out2; } @@ -1922,14 +1995,14 @@ tgs_rep2(KDC_REQ_BODY *b, *csec = malloc(sizeof(**csec)); if (*csec == NULL) { krb5_free_authenticator(context, &auth); - kdc_log(0, "malloc failed"); + kdc_log(context, config, 0, "malloc failed"); goto out2; } **csec = auth->ctime; *cusec = malloc(sizeof(**cusec)); if (*cusec == NULL) { krb5_free_authenticator(context, &auth); - kdc_log(0, "malloc failed"); + kdc_log(context, config, 0, "malloc failed"); goto out2; } **csec = auth->cusec; @@ -1941,7 +2014,8 @@ tgs_rep2(KDC_REQ_BODY *b, tgt = &ticket->ticket; - ret = tgs_check_authenticator(ac, b, &e_text, &tgt->key); + ret = tgs_check_authenticator(context, config, + ac, b, &e_text, &tgt->key); if (b->enc_authorization_data) { krb5_keyblock *subkey; @@ -1951,7 +2025,7 @@ tgs_rep2(KDC_REQ_BODY *b, &subkey); if(ret){ krb5_auth_con_free(context, ac); - kdc_log(0, "Failed to get remote subkey: %s", + kdc_log(context, config, 0, "Failed to get remote subkey: %s", krb5_get_err_text(context, ret)); goto out2; } @@ -1959,21 +2033,22 @@ tgs_rep2(KDC_REQ_BODY *b, ret = krb5_auth_con_getkey(context, ac, &subkey); if(ret) { krb5_auth_con_free(context, ac); - kdc_log(0, "Failed to get session key: %s", + kdc_log(context, config, 0, "Failed to get session key: %s", krb5_get_err_text(context, ret)); goto out2; } } if(subkey == NULL){ krb5_auth_con_free(context, ac); - kdc_log(0, "Failed to get key for enc-authorization-data"); + kdc_log(context, config, 0, + "Failed to get key for enc-authorization-data"); ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */ goto out2; } ret = krb5_crypto_init(context, subkey, 0, &crypto); if (ret) { krb5_auth_con_free(context, ac); - kdc_log(0, "krb5_crypto_init failed: %s", + kdc_log(context, config, 0, "krb5_crypto_init failed: %s", krb5_get_err_text(context, ret)); goto out2; } @@ -1985,7 +2060,7 @@ tgs_rep2(KDC_REQ_BODY *b, krb5_crypto_destroy(context, crypto); if(ret){ krb5_auth_con_free(context, ac); - kdc_log(0, "Failed to decrypt enc-authorization-data"); + kdc_log(context, config, 0, "Failed to decrypt enc-authorization-data"); ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */ goto out2; } @@ -1996,7 +2071,7 @@ tgs_rep2(KDC_REQ_BODY *b, krb5_auth_con_free(context, ac); free(auth_data); auth_data = NULL; - kdc_log(0, "Failed to decode authorization data"); + kdc_log(context, config, 0, "Failed to decode authorization data"); ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */ goto out2; } @@ -2005,7 +2080,7 @@ tgs_rep2(KDC_REQ_BODY *b, krb5_auth_con_free(context, ac); if(ret){ - kdc_log(0, "Failed to verify authenticator: %s", + kdc_log(context, config, 0, "Failed to verify authenticator: %s", krb5_get_err_text(context, ret)); goto out2; } @@ -2030,17 +2105,19 @@ tgs_rep2(KDC_REQ_BODY *b, if(b->additional_tickets == NULL || b->additional_tickets->len == 0){ ret = KRB5KDC_ERR_BADOPTION; /* ? */ - kdc_log(0, "No second ticket present in request"); + kdc_log(context, config, 0, + "No second ticket present in request"); goto out; } t = &b->additional_tickets->val[0]; if(!get_krbtgt_realm(&t->sname)){ - kdc_log(0, "Additional ticket is not a ticket-granting ticket"); + kdc_log(context, config, 0, + "Additional ticket is not a ticket-granting ticket"); ret = KRB5KDC_ERR_POLICY; goto out2; } _krb5_principalname2krb5_principal(&p, t->sname, t->realm); - ret = db_fetch(p, &uu); + ret = db_fetch(context, config, p, &uu); krb5_free_principal(context, p); if(ret){ if (ret == HDB_ERR_NOENTRY) @@ -2072,12 +2149,14 @@ tgs_rep2(KDC_REQ_BODY *b, asn1_KDCOptions_units(), opt_str, sizeof(opt_str)); if(*opt_str) - kdc_log(0, "TGS-REQ %s from %s for %s [%s]", + kdc_log(context, config, 0, + "TGS-REQ %s from %s for %s [%s]", cpn, from, spn, opt_str); else - kdc_log(0, "TGS-REQ %s from %s for %s", cpn, from, spn); + kdc_log(context, config, 0, + "TGS-REQ %s from %s for %s", cpn, from, spn); server_lookup: - ret = db_fetch(sp, &server); + ret = db_fetch(context, config, sp, &server); if(ret){ const char *new_rlm; @@ -2086,9 +2165,9 @@ tgs_rep2(KDC_REQ_BODY *b, if ((req_rlm = get_krbtgt_realm(&sp->name)) != NULL) { if(nloop++ < 2) { - new_rlm = find_rpath(tgt->crealm, req_rlm); + new_rlm = find_rpath(context, tgt->crealm, req_rlm); if(new_rlm) { - kdc_log(5, "krbtgt for realm %s not found, trying %s", + kdc_log(context, config, 5, "krbtgt for realm %s not found, trying %s", req_rlm, new_rlm); krb5_free_principal(context, sp); free(spn); @@ -2100,9 +2179,10 @@ tgs_rep2(KDC_REQ_BODY *b, goto server_lookup; } } - } else if(need_referral(sp, &realms)) { + } else if(need_referral(context, sp, &realms)) { if (strcmp(realms[0], sp->realm) != 0) { - kdc_log(5, "returning a referral to realm %s for " + kdc_log(context, config, 5, + "Returning a referral to realm %s for " "server %s that was not found", realms[0], spn); krb5_free_principal(context, sp); @@ -2117,21 +2197,23 @@ tgs_rep2(KDC_REQ_BODY *b, } krb5_free_host_realm(context, realms); } - kdc_log(0, "Server not found in database: %s: %s", spn, + kdc_log(context, config, 0, + "Server not found in database: %s: %s", spn, krb5_get_err_text(context, ret)); if (ret == HDB_ERR_NOENTRY) ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; goto out; } - ret = db_fetch(cp, &client); + ret = db_fetch(context, config, cp, &client); if(ret) - kdc_log(1, "Client not found in database: %s: %s", + kdc_log(context, config, 1, "Client not found in database: %s: %s", cpn, krb5_get_err_text(context, ret)); #if 0 /* XXX check client only if same realm as krbtgt-instance */ if(ret){ - kdc_log(0, "Client not found in database: %s: %s", + kdc_log(context, config, 0, + "Client not found in database: %s: %s", cpn, krb5_get_err_text(context, ret)); if (ret == HDB_ERR_NOENTRY) ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; @@ -2143,7 +2225,9 @@ tgs_rep2(KDC_REQ_BODY *b, krb5_principal_get_comp_string(context, krbtgt->principal, 1)) != 0) { char *tpn; ret = krb5_unparse_name(context, krbtgt->principal, &tpn); - kdc_log(0, "Request with wrong krbtgt: %s", (ret == 0) ? tpn : ""); + kdc_log(context, config, 0, + "Request with wrong krbtgt: %s", + (ret == 0) ? tpn : ""); if(ret == 0) free(tpn); ret = KRB5KRB_AP_ERR_NOT_US; @@ -2151,7 +2235,8 @@ tgs_rep2(KDC_REQ_BODY *b, } - ret = check_flags(client, cpn, server, spn, FALSE); + ret = check_flags(context, config, + client, cpn, server, spn, FALSE); if(ret) goto out; @@ -2159,19 +2244,20 @@ tgs_rep2(KDC_REQ_BODY *b, !krb5_principal_compare(context, krbtgt->principal, server->principal)){ - kdc_log(0, "Inconsistent request."); + kdc_log(context, config, 0, "Inconsistent request."); ret = KRB5KDC_ERR_SERVER_NOMATCH; goto out; } /* check for valid set of addresses */ - if(!check_addresses(tgt->caddr, from_addr)) { + if(!check_addresses(context, config, tgt->caddr, from_addr)) { ret = KRB5KRB_AP_ERR_BADADDR; - kdc_log(0, "Request from wrong address"); + kdc_log(context, config, 0, "Request from wrong address"); goto out; } - ret = tgs_make_reply(b, + ret = tgs_make_reply(context, config, + b, tgt, b->kdc_options.enc_tkt_in_skey ? &adtkt : NULL, auth_data, @@ -2188,9 +2274,9 @@ tgs_rep2(KDC_REQ_BODY *b, free(cpn); if(server) - free_ent(server); + free_ent(context, server); if(client) - free_ent(client); + free_ent(context, client); } out2: if(ret) { @@ -2219,14 +2305,16 @@ out2: } if(krbtgt) - free_ent(krbtgt); + free_ent(context, krbtgt); return ret; } krb5_error_code -tgs_rep(KDC_REQ *req, +tgs_rep(krb5_context context, + struct krb5_kdc_configuration *config, + KDC_REQ *req, krb5_data *data, const char *from, struct sockaddr *from_addr) @@ -2239,7 +2327,8 @@ tgs_rep(KDC_REQ *req, if(req->padata == NULL){ ret = KRB5KDC_ERR_PREAUTH_REQUIRED; /* XXX ??? */ - kdc_log(0, "TGS-REQ from %s without PA-DATA", from); + kdc_log(context, config, 0, + "TGS-REQ from %s without PA-DATA", from); goto out; } @@ -2248,10 +2337,12 @@ tgs_rep(KDC_REQ *req, if(tgs_req == NULL){ ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP; - kdc_log(0, "TGS-REQ from %s without PA-TGS-REQ", from); + kdc_log(context, config, 0, + "TGS-REQ from %s without PA-TGS-REQ", from); goto out; } - ret = tgs_rep2(&req->req_body, tgs_req, data, from, from_addr, + ret = tgs_rep2(context, config, + &req->req_body, tgs_req, data, from, from_addr, &csec, &cusec); out: if(ret && data->data == NULL){ diff --git a/kdc/log.c b/kdc/log.c index fa41de6a8..8a2fec0a9 100644 --- a/kdc/log.c +++ b/kdc/log.c @@ -34,51 +34,56 @@ #include "kdc_locl.h" RCSID("$Id$"); -static krb5_log_facility *logf; - void -kdc_openlog(void) +kdc_openlog(krb5_context context, + struct krb5_kdc_configuration *config) { char **s = NULL, **p; - krb5_initlog(context, "kdc", &logf); + krb5_initlog(context, "kdc", &config->logf); s = krb5_config_get_strings(context, NULL, "kdc", "logging", NULL); if(s == NULL) s = krb5_config_get_strings(context, NULL, "logging", "kdc", NULL); if(s){ for(p = s; *p; p++) - krb5_addlog_dest(context, logf, *p); + krb5_addlog_dest(context, config->logf, *p); krb5_config_free_strings(s); }else - krb5_addlog_dest(context, logf, DEFAULT_LOG_DEST); - krb5_set_warn_dest(context, logf); + krb5_addlog_dest(context, config->logf, DEFAULT_LOG_DEST); + krb5_set_warn_dest(context, config->logf); } char* -kdc_log_msg_va(int level, const char *fmt, va_list ap) +kdc_log_msg_va(krb5_context context, + struct krb5_kdc_configuration *config, + int level, const char *fmt, va_list ap) { char *msg; - krb5_vlog_msg(context, logf, &msg, level, fmt, ap); + krb5_vlog_msg(context, config->logf, &msg, level, fmt, ap); return msg; } char* -kdc_log_msg(int level, const char *fmt, ...) +kdc_log_msg(krb5_context context, + struct krb5_kdc_configuration *config, + int level, const char *fmt, ...) { va_list ap; char *s; va_start(ap, fmt); - s = kdc_log_msg_va(level, fmt, ap); + s = kdc_log_msg_va(context, config, level, fmt, ap); va_end(ap); return s; } void -kdc_log(int level, const char *fmt, ...) +kdc_log(krb5_context context, + struct krb5_kdc_configuration *config, + int level, const char *fmt, ...) { va_list ap; char *s; va_start(ap, fmt); - s = kdc_log_msg_va(level, fmt, ap); + s = kdc_log_msg_va(context, config, level, fmt, ap); if(s) free(s); va_end(ap); } diff --git a/kdc/main.c b/kdc/main.c index 68b28f60a..7074b84ec 100644 --- a/kdc/main.c +++ b/kdc/main.c @@ -39,9 +39,8 @@ RCSID("$Id$"); sig_atomic_t exit_flag = 0; -krb5_context context; -extern int detach_from_console; +int detach_from_console = -1; static RETSIGTYPE sigterm(int sig) @@ -53,6 +52,9 @@ int main(int argc, char **argv) { krb5_error_code ret; + krb5_context context; + struct krb5_kdc_configuration *config; + setprogname(argv[0]); ret = krb5_init_context(&context); @@ -61,32 +63,7 @@ main(int argc, char **argv) else if (ret) errx (1, "krb5_init_context failed: %d", ret); - configure(argc, argv); - - if(databases == NULL) { - db = malloc(sizeof(*db)); - num_db = 1; - ret = hdb_create(context, &db[0], NULL); - if(ret) - krb5_err(context, 1, ret, "hdb_create %s", HDB_DEFAULT_DB); - ret = hdb_set_master_keyfile(context, db[0], NULL); - if (ret) - krb5_err(context, 1, ret, "hdb_set_master_keyfile"); - } else { - struct dbinfo *d; - int i; - /* count databases */ - for(d = databases, i = 0; d; d = d->next, i++); - db = malloc(i * sizeof(*db)); - for(d = databases, num_db = 0; d; d = d->next, num_db++) { - ret = hdb_create(context, &db[num_db], d->dbname); - if(ret) - krb5_err(context, 1, ret, "hdb_create %s", d->dbname); - ret = hdb_set_master_keyfile(context, db[num_db], d->mkey_file); - if (ret) - krb5_err(context, 1, ret, "hdb_set_master_keyfile"); - } - } + config = configure(context, argc, argv); #ifdef HAVE_SIGACTION { @@ -112,7 +89,7 @@ main(int argc, char **argv) if (detach_from_console) daemon(0, 0); pidfile(NULL); - loop(); + loop(context, config); krb5_free_context(context); return 0; } diff --git a/kdc/misc.c b/kdc/misc.c index b51c99852..3626cdc02 100644 --- a/kdc/misc.c +++ b/kdc/misc.c @@ -38,7 +38,10 @@ RCSID("$Id$"); struct timeval now; krb5_error_code -db_fetch(krb5_principal principal, hdb_entry **h) +db_fetch(krb5_context context, + struct krb5_kdc_configuration *config, + krb5_principal principal, + hdb_entry **h) { hdb_entry *ent; krb5_error_code ret = HDB_ERR_NOENTRY; @@ -49,15 +52,18 @@ db_fetch(krb5_principal principal, hdb_entry **h) return ENOMEM; ent->principal = principal; - for(i = 0; i < num_db; i++) { - ret = db[i]->hdb_open(context, db[i], O_RDONLY, 0); + for(i = 0; i < config->num_db; i++) { + ret = config->db[i]->hdb_open(context, config->db[i], O_RDONLY, 0); if (ret) { - kdc_log(0, "Failed to open database: %s", + kdc_log(context, config, 0, "Failed to open database: %s", krb5_get_err_text(context, ret)); continue; } - ret = db[i]->hdb_fetch(context, db[i], HDB_F_DECRYPT, ent); - db[i]->hdb_close(context, db[i]); + ret = config->db[i]->hdb_fetch(context, + config->db[i], + HDB_F_DECRYPT, + ent); + config->db[i]->hdb_close(context, config->db[i]); if(ret == 0) { *h = ent; return 0; @@ -68,7 +74,7 @@ db_fetch(krb5_principal principal, hdb_entry **h) } void -free_ent(hdb_entry *ent) +free_ent(krb5_context context, hdb_entry *ent) { hdb_free_entry (context, ent); free (ent); diff --git a/kdc/mit_dump.c b/kdc/mit_dump.c index bf6ac2d6a..9955e7334 100644 --- a/kdc/mit_dump.c +++ b/kdc/mit_dump.c @@ -168,7 +168,6 @@ fix_salt(krb5_context context, hdb_entry *ent, int key_num) { size_t len; int i; - krb5_error_code ret; char *p; len = 0; @@ -219,7 +218,7 @@ int mit_prop_dump(void *arg, const char *file) { krb5_error_code ret; - char buf [1024]; + char line [2048]; FILE *f; int lineno = 0; struct hdb_entry ent; @@ -230,8 +229,8 @@ mit_prop_dump(void *arg, const char *file) if(f == NULL) return errno; - while(fgets(buf, sizeof(buf), f)) { - char *p = buf, *q; + while(fgets(line, sizeof(line), f)) { + char *p = line, *q; int i; diff --git a/kdc/pkinit.c b/kdc/pkinit.c index 067479149..381050ca7 100644 --- a/kdc/pkinit.c +++ b/kdc/pkinit.c @@ -49,9 +49,6 @@ RCSID("$Id$"); #include #include -int enable_pkinit = 0; -int enable_pkinit_princ_in_cert = 0; - /* XXX copied from lib/krb5/pkinit.c */ struct krb5_pk_identity { EVP_PKEY *private_key; diff --git a/kdc/process.c b/kdc/process.c new file mode 100644 index 000000000..ef4727019 --- /dev/null +++ b/kdc/process.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "kdc_locl.h" + +RCSID("$Id$"); + +/* + * handle the request in `buf, len', from `addr' (or `from' as a string), + * sending a reply in `reply'. + */ + +int +krb5_kdc_process_generic_request(krb5_context context, + struct krb5_kdc_configuration *config, + unsigned char *buf, + size_t len, + krb5_data *reply, + krb5_boolean *prependlength, + const char *from, + struct sockaddr *addr) +{ + KDC_REQ req; + Ticket ticket; + krb5_error_code ret; + size_t i; + + gettimeofday(&now, NULL); + if(decode_AS_REQ(buf, len, &req, &i) == 0){ + ret = as_rep(context, config, &req, reply, from, addr); + free_AS_REQ(&req); + return ret; + }else if(decode_TGS_REQ(buf, len, &req, &i) == 0){ + ret = tgs_rep(context, config, &req, reply, from, addr); + free_TGS_REQ(&req); + return ret; + }else if(decode_Ticket(buf, len, &ticket, &i) == 0){ + ret = do_524(context, config, &ticket, reply, from, addr); + free_Ticket(&ticket); + return ret; + } else if(maybe_version4(buf, len)){ + *prependlength = FALSE; /* elbitapmoc sdrawkcab XXX */ + do_version4(context, config, buf, len, reply, from, + (struct sockaddr_in*)addr); + return 0; + } else if (config->enable_kaserver) { + ret = do_kaserver(context, config, buf, len, reply, from, + (struct sockaddr_in*)addr); + return ret; + } + + return -1; +} + +/* + * handle the request in `buf, len', from `addr' (or `from' as a string), + * sending a reply in `reply'. + * + * This only processes krb5 requests + */ + +int krb5_kdc_process_krb5_request(krb5_context context, + struct krb5_kdc_configuration *config, + unsigned char *buf, + size_t len, + krb5_data *reply, + const char *from, + struct sockaddr *addr) +{ + KDC_REQ req; + krb5_error_code ret; + size_t i; + + gettimeofday(&now, NULL); + if(decode_AS_REQ(buf, len, &req, &i) == 0){ + ret = as_rep(context, config, &req, reply, from, addr); + free_AS_REQ(&req); + return ret; + }else if(decode_TGS_REQ(buf, len, &req, &i) == 0){ + ret = tgs_rep(context, config, &req, reply, from, addr); + free_TGS_REQ(&req); + return ret; + } + return -1; +}