krb5 commit: Eliminate some KDC globals
Tom Yu
tlyu at MIT.EDU
Mon Oct 15 20:27:43 EDT 2012
https://github.com/krb5/krb5/commit/0a2f14f752c32a24200363cc6b6ae64a92f81379
commit 0a2f14f752c32a24200363cc6b6ae64a92f81379
Author: Tom Yu <tlyu at mit.edu>
Date: Fri Sep 7 20:18:41 2012 -0400
Eliminate some KDC globals
Make kdc_active_realm a local variable in every function that needs
it. Pass it around in various state structures as needed. Keep the
macros that reference its members remain for now.
src/kdc/dispatch.c | 48 +++++++---
src/kdc/do_as_req.c | 34 +++++---
src/kdc/do_tgs_req.c | 74 +++++++++------
src/kdc/extern.c | 2 +-
src/kdc/extern.h | 68 --------------
src/kdc/fast_util.c | 32 +++++--
src/kdc/kdc_preauth.c | 22 +++---
src/kdc/kdc_util.c | 196 +++++++++++++++++++++-------------------
src/kdc/kdc_util.h | 64 +++++--------
src/kdc/main.c | 85 ++++++++++--------
src/kdc/realm_data.h | 107 ++++++++++++++++++++++
src/kdc/replay.c | 20 +++--
src/kdc/reqstate.h | 53 +++++++++++
src/kdc/rtest.c | 7 ++-
src/lib/apputils/net-server.c | 4 +-
15 files changed, 489 insertions(+), 327 deletions(-)
diff --git a/src/kdc/dispatch.c b/src/kdc/dispatch.c
index e3f43bc..68c67f4 100644
--- a/src/kdc/dispatch.c
+++ b/src/kdc/dispatch.c
@@ -28,19 +28,23 @@
#include "kdc_util.h"
#include "extern.h"
#include "adm_proto.h"
+#include "realm_data.h"
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
static krb5_int32 last_usec = 0, last_os_random = 0;
-static krb5_error_code make_too_big_error (krb5_data **out);
+static krb5_error_code make_too_big_error(kdc_realm_t *kdc_active_realm,
+ krb5_data **out);
struct dispatch_state {
loop_respond_fn respond;
void *arg;
krb5_data *request;
int is_tcp;
+ kdc_realm_t *active_realm;
+ krb5_context kdc_err_context;
};
static void
@@ -49,12 +53,13 @@ finish_dispatch(struct dispatch_state *state, krb5_error_code code,
{
loop_respond_fn oldrespond = state->respond;
void *oldarg = state->arg;
+ kdc_realm_t *kdc_active_realm = state->active_realm;
if (state->is_tcp == 0 && response &&
response->length > (unsigned int)max_dgram_reply_size) {
krb5_free_data(kdc_context, response);
response = NULL;
- code = make_too_big_error(&response);
+ code = make_too_big_error(kdc_active_realm, &response);
if (code)
krb5_klog_syslog(LOG_ERR, "error constructing "
"KRB_ERR_RESPONSE_TOO_BIG error: %s",
@@ -69,16 +74,17 @@ static void
finish_dispatch_cache(void *arg, krb5_error_code code, krb5_data *response)
{
struct dispatch_state *state = arg;
+ krb5_context kdc_err_context = state->kdc_err_context;
#ifndef NOCACHE
/* Remove the null cache entry unless we actually want to discard this
* request. */
if (code != KRB5KDC_ERR_DISCARD)
- kdc_remove_lookaside(kdc_context, state->request);
+ kdc_remove_lookaside(kdc_err_context, state->request);
/* Put the response into the lookaside buffer (if we produced one). */
if (code == 0 && response != NULL)
- kdc_insert_lookaside(state->request, response);
+ kdc_insert_lookaside(kdc_err_context, state->request, response);
#endif
finish_dispatch(state, code, response);
@@ -94,6 +100,8 @@ dispatch(void *cb, struct sockaddr *local_saddr,
krb5_int32 now, now_usec;
krb5_data *response = NULL;
struct dispatch_state *state;
+ struct server_handle *handle = cb;
+ krb5_context kdc_err_context = handle->kdc_err_context;
state = k5alloc(sizeof(*state), &retval);
if (state == NULL) {
@@ -104,12 +112,13 @@ dispatch(void *cb, struct sockaddr *local_saddr,
state->arg = arg;
state->request = pkt;
state->is_tcp = is_tcp;
+ state->kdc_err_context = kdc_err_context;
/* decode incoming packet, and dispatch */
#ifndef NOCACHE
/* try the replay lookaside buffer */
- if (kdc_check_lookaside(pkt, &response)) {
+ if (kdc_check_lookaside(kdc_err_context, pkt, &response)) {
/* a hit! */
const char *name = 0;
char buf[46];
@@ -134,7 +143,7 @@ dispatch(void *cb, struct sockaddr *local_saddr,
/* Insert a NULL entry into the lookaside to indicate that this request
* is currently being processed. */
- kdc_insert_lookaside(pkt, NULL);
+ kdc_insert_lookaside(kdc_err_context, pkt, NULL);
#endif
retval = krb5_crypto_us_timeofday(&now, &now_usec);
@@ -145,21 +154,21 @@ dispatch(void *cb, struct sockaddr *local_saddr,
last_os_random = now;
/* Grab random data from OS every hour*/
if(now-last_os_random >= 60*60) {
- krb5_c_random_os_entropy(kdc_context, 0, NULL);
+ krb5_c_random_os_entropy(kdc_err_context, 0, NULL);
last_os_random = now;
}
data.length = sizeof(krb5_int32);
data.data = (void *) &usec_difference;
- krb5_c_random_add_entropy(kdc_context,
+ krb5_c_random_add_entropy(kdc_err_context,
KRB5_C_RANDSOURCE_TIMING, &data);
last_usec = now_usec;
}
/* try TGS_REQ first; they are more common! */
if (krb5_is_tgs_req(pkt)) {
- retval = process_tgs_req(pkt, from, &response);
+ retval = process_tgs_req(handle, pkt, from, &response);
} else if (krb5_is_as_req(pkt)) {
if (!(retval = decode_krb5_as_req(pkt, &as_req))) {
/*
@@ -167,13 +176,15 @@ dispatch(void *cb, struct sockaddr *local_saddr,
* pointer.
* process_as_req frees the request if it is called
*/
- if (!(retval = setup_server_realm(as_req->server))) {
- process_as_req(as_req, pkt, from, vctx, finish_dispatch_cache,
- state);
+ state->active_realm = setup_server_realm(handle, as_req->server);
+ if (state->active_realm != NULL) {
+ process_as_req(as_req, pkt, from, state->active_realm, vctx,
+ finish_dispatch_cache, state);
return;
+ } else {
+ retval = KRB5KDC_ERR_WRONG_REALM;
+ krb5_free_kdc_req(kdc_err_context, as_req);
}
- else
- krb5_free_kdc_req(kdc_context, as_req);
}
} else
retval = KRB5KRB_AP_ERR_MSG_TYPE;
@@ -182,7 +193,7 @@ dispatch(void *cb, struct sockaddr *local_saddr,
}
static krb5_error_code
-make_too_big_error (krb5_data **out)
+make_too_big_error(kdc_realm_t *kdc_active_realm, krb5_data **out)
{
krb5_error errpkt;
krb5_error_code retval;
@@ -213,3 +224,10 @@ make_too_big_error (krb5_data **out)
*out = scratch;
return 0;
}
+
+krb5_context get_context(void *handle)
+{
+ struct server_handle *sh = handle;
+
+ return sh->kdc_err_context;
+}
diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c
index 4ca712d..79da300 100644
--- a/src/kdc/do_as_req.c
+++ b/src/kdc/do_as_req.c
@@ -119,6 +119,8 @@ struct as_req_state {
const krb5_fulladdr *from;
krb5_error_code preauth_err;
+
+ kdc_realm_t *active_realm;
};
static void
@@ -134,6 +136,7 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode)
krb5_enctype useenctype;
loop_respond_fn oldrespond;
void *oldarg;
+ kdc_realm_t *kdc_active_realm = state->active_realm;
assert(state);
oldrespond = state->respond;
@@ -315,7 +318,7 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode)
state->reply.enc_part.ciphertext.length);
free(state->reply.enc_part.ciphertext.data);
- log_as_req(state->from, state->request, &state->reply,
+ log_as_req(kdc_context, state->from, state->request, &state->reply,
state->client, state->cname, state->server,
state->sname, state->authtime, 0, 0, 0);
did_log = 1;
@@ -330,7 +333,8 @@ egress:
emsg = krb5_get_error_message(kdc_context, errcode);
if (state->status) {
- log_as_req(state->from, state->request, &state->reply, state->client,
+ log_as_req(kdc_context,
+ state->from, state->request, &state->reply, state->client,
state->cname, state->server, state->sname, state->authtime,
state->status, errcode, emsg);
did_log = 1;
@@ -438,8 +442,8 @@ finish_preauth(void *arg, krb5_error_code code)
/*ARGSUSED*/
void
process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
- const krb5_fulladdr *from, verto_ctx *vctx,
- loop_respond_fn respond, void *arg)
+ const krb5_fulladdr *from, kdc_realm_t *kdc_active_realm,
+ verto_ctx *vctx, loop_respond_fn respond, void *arg)
{
krb5_error_code errcode;
krb5_timestamp rtime;
@@ -458,17 +462,18 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
state->request = request;
state->req_pkt = req_pkt;
state->from = from;
+ state->active_realm = kdc_active_realm;
+ errcode = kdc_make_rstate(kdc_active_realm, &state->rstate);
+ if (errcode != 0) {
+ (*respond)(arg, errcode, NULL);
+ return;
+ }
if (state->request->msg_type != KRB5_AS_REQ) {
state->status = "msg_type mismatch";
errcode = KRB5_BADMSGTYPE;
goto errout;
}
- errcode = kdc_make_rstate(&state->rstate);
- if (errcode != 0) {
- state->status = "constructing state";
- goto errout;
- }
if (fetch_asn1_field((unsigned char *) req_pkt->data,
1, 4, &encoded_req_body) != 0) {
errcode = ASN1_BAD_ID;
@@ -558,7 +563,7 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
* If the backend returned a principal that is not in the local
* realm, then we need to refer the client to that realm.
*/
- if (!is_local_principal(state->client->princ)) {
+ if (!is_local_principal(kdc_active_realm, state->client->princ)) {
/* Entry is a referral to another realm */
state->status = "REFERRAL";
errcode = KRB5KDC_ERR_WRONG_REALM;
@@ -589,7 +594,8 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
}
state->authtime = state->kdc_time; /* for audit_as_request() */
- if ((errcode = validate_as_request(state->request, *state->client,
+ if ((errcode = validate_as_request(kdc_active_realm,
+ state->request, *state->client,
*state->server, state->kdc_time,
&state->status, &state->e_data))) {
if (!state->status)
@@ -601,7 +607,7 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
/*
* Select the keytype for the ticket session key.
*/
- if ((useenctype = select_session_keytype(kdc_context, state->server,
+ if ((useenctype = select_session_keytype(kdc_active_realm, state->server,
state->request->nktypes,
state->request->ktype)) == 0) {
/* unsupported ktype */
@@ -669,7 +675,8 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
} else
state->enc_tkt_reply.times.starttime = state->kdc_time;
- kdc_get_ticket_endtime(kdc_context, state->enc_tkt_reply.times.starttime,
+ kdc_get_ticket_endtime(kdc_active_realm,
+ state->enc_tkt_reply.times.starttime,
kdc_infinity, state->request->till, state->client,
state->server, &state->enc_tkt_reply.times.endtime);
@@ -759,6 +766,7 @@ prepare_error_as (struct kdc_request_state *rstate, krb5_kdc_req *request,
krb5_error errpkt;
krb5_error_code retval;
krb5_data *scratch = NULL, *e_data_asn1 = NULL, *fast_edata = NULL;
+ kdc_realm_t *kdc_active_realm = rstate->realm_data;
errpkt.ctime = request->nonce;
errpkt.cusec = 0;
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
index 8a6d93c..c45fe87 100644
--- a/src/kdc/do_tgs_req.c
+++ b/src/kdc/do_tgs_req.c
@@ -69,19 +69,21 @@
#include <ctype.h>
static krb5_error_code
-find_alternate_tgs(krb5_kdc_req *,krb5_db_entry **);
+find_alternate_tgs(struct kdc_request_state *, krb5_kdc_req *,
+ krb5_db_entry **);
static krb5_error_code
prepare_error_tgs(struct kdc_request_state *, krb5_kdc_req *,krb5_ticket *,int,
krb5_principal,krb5_data **,const char *, krb5_pa_data **);
static krb5_int32
-prep_reprocess_req(krb5_kdc_req *,krb5_principal *);
+prep_reprocess_req(struct kdc_request_state *, krb5_kdc_req *,
+ krb5_principal *);
/*ARGSUSED*/
krb5_error_code
-process_tgs_req(krb5_data *pkt, const krb5_fulladdr *from,
- krb5_data **response)
+process_tgs_req(struct server_handle *handle, krb5_data *pkt,
+ const krb5_fulladdr *from, krb5_data **response)
{
krb5_keyblock * subkey = 0;
krb5_keyblock * tgskey = 0;
@@ -124,6 +126,7 @@ process_tgs_req(krb5_data *pkt, const krb5_fulladdr *from,
krb5_pa_data *pa_tgs_req; /*points into request*/
krb5_data scratch;
krb5_pa_data **e_data = NULL;
+ kdc_realm_t *kdc_active_realm = NULL;
reply.padata = 0; /* For cleanup handler */
reply_encpart.enc_padata = 0;
@@ -135,18 +138,25 @@ process_tgs_req(krb5_data *pkt, const krb5_fulladdr *from,
if (retval)
return retval;
if (request->msg_type != KRB5_TGS_REQ) {
- krb5_free_kdc_req(kdc_context, request);
+ krb5_free_kdc_req(handle->kdc_err_context, request);
return KRB5_BADMSGTYPE;
}
/*
* setup_server_realm() sets up the global realm-specific data pointer.
*/
- if ((retval = setup_server_realm(request->server))) {
- krb5_free_kdc_req(kdc_context, request);
- return retval;
+ kdc_active_realm = setup_server_realm(handle, request->server);
+ if (kdc_active_realm == NULL) {
+ krb5_free_kdc_req(handle->kdc_err_context, request);
+ return KRB5KDC_ERR_WRONG_REALM;
+ }
+ errcode = kdc_make_rstate(kdc_active_realm, &state);
+ if (errcode !=0) {
+ krb5_free_kdc_req(handle->kdc_err_context, request);
+ return errcode;
}
- errcode = kdc_process_tgs_req(request, from, pkt, &header_ticket,
+ errcode = kdc_process_tgs_req(kdc_active_realm,
+ request, from, pkt, &header_ticket,
&krbtgt, &tgskey, &subkey, &pa_tgs_req);
if (header_ticket && header_ticket->enc_part2 &&
(errcode2 = krb5_unparse_name(kdc_context,
@@ -168,11 +178,6 @@ process_tgs_req(krb5_data *pkt, const krb5_fulladdr *from,
status="UNEXPECTED NULL in header_ticket";
goto cleanup;
}
- errcode = kdc_make_rstate(&state);
- if (errcode !=0) {
- status = "making state";
- goto cleanup;
- }
scratch.length = pa_tgs_req->length;
scratch.data = (char *) pa_tgs_req->contents;
errcode = kdc_find_fast(&request, &scratch, subkey,
@@ -238,7 +243,7 @@ tgt_again:
tgs_1 = krb5_princ_component(kdc_context, tgs_server, 1);
if (!tgs_1 || !data_eq(*server_1, *tgs_1)) {
- errcode = find_alternate_tgs(request, &server);
+ errcode = find_alternate_tgs(state, request, &server);
firstpass = 0;
if (errcode == 0)
goto tgt_again;
@@ -249,7 +254,7 @@ tgt_again:
goto cleanup;
} else if ( db_ref_done == FALSE) {
- retval = prep_reprocess_req(request, &krbtgt_princ);
+ retval = prep_reprocess_req(state, request, &krbtgt_princ);
if (!retval) {
krb5_free_principal(kdc_context, request->server);
request->server = NULL;
@@ -275,7 +280,8 @@ tgt_again:
goto cleanup;
}
- if ((retval = validate_tgs_request(request, *server, header_ticket,
+ if ((retval = validate_tgs_request(kdc_active_realm,
+ request, *server, header_ticket,
kdc_time, &status, &e_data))) {
if (!status)
status = "UNKNOWN_REASON";
@@ -283,14 +289,14 @@ tgt_again:
goto cleanup;
}
- if (!is_local_principal(header_enc_tkt->client))
+ if (!is_local_principal(kdc_active_realm, header_enc_tkt->client))
setflag(c_flags, KRB5_KDB_FLAG_CROSS_REALM);
is_referral = krb5_is_tgs_principal(server->princ) &&
!krb5_principal_compare(kdc_context, tgs_server, server->princ);
/* Check for protocol transition */
- errcode = kdc_process_s4u2self_req(kdc_context,
+ errcode = kdc_process_s4u2self_req(kdc_active_realm,
request,
header_enc_tkt->client,
server,
@@ -327,7 +333,8 @@ tgt_again:
/*
* Get the key for the second ticket, and decrypt it.
*/
- if ((errcode = kdc_get_server_key(request->second_ticket[st_idx],
+ if ((errcode = kdc_get_server_key(kdc_context,
+ request->second_ticket[st_idx],
c_flags,
TRUE, /* match_enctype */
&st_client,
@@ -362,7 +369,7 @@ tgt_again:
if (isflagset(request->kdc_options, KDC_OPT_CNAME_IN_ADDL_TKT)) {
/* Do constrained delegation protocol and authorization checks */
- errcode = kdc_process_s4u2proxy_req(kdc_context,
+ errcode = kdc_process_s4u2proxy_req(kdc_active_realm,
request,
request->second_ticket[st_idx]->enc_part2,
st_client,
@@ -388,7 +395,7 @@ tgt_again:
* Select the keytype for the ticket session key.
*/
if ((useenctype == 0) &&
- (useenctype = select_session_keytype(kdc_context, server,
+ (useenctype = select_session_keytype(kdc_active_realm, server,
request->nktypes,
request->ktype)) == 0) {
/* unsupported ktype */
@@ -545,7 +552,7 @@ tgt_again:
/* not a renew request */
enc_tkt_reply.times.starttime = kdc_time;
- kdc_get_ticket_endtime(kdc_context, enc_tkt_reply.times.starttime,
+ kdc_get_ticket_endtime(kdc_active_realm, enc_tkt_reply.times.starttime,
header_enc_tkt->times.endtime, request->till,
client, server, &enc_tkt_reply.times.endtime);
@@ -702,8 +709,9 @@ tgt_again:
* listed).
*/
/* realm compare is like strcmp, but knows how to deal with these args */
- if (realm_compare(header_ticket->server, tgs_server) ||
- realm_compare(header_ticket->server, enc_tkt_reply.client)) {
+ if (krb5_realm_compare(kdc_context, header_ticket->server, tgs_server) ||
+ krb5_realm_compare(kdc_context, header_ticket->server,
+ enc_tkt_reply.client)) {
/* tgt issued by local realm or issued by realm of client */
enc_tkt_reply.transited = header_enc_tkt->transited;
} else {
@@ -744,7 +752,7 @@ tgt_again:
unsigned int tlen;
char *tdots;
- errcode = kdc_check_transited_list (kdc_context,
+ errcode = kdc_check_transited_list (kdc_active_realm,
&enc_tkt_reply.transited.tr_contents,
krb5_princ_realm (kdc_context, header_enc_tkt->client),
krb5_princ_realm (kdc_context, request->server));
@@ -825,7 +833,8 @@ tgt_again:
/* Start assembling the response */
reply.msg_type = KRB5_TGS_REP;
if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION) &&
- find_pa_data(request->padata, KRB5_PADATA_S4U_X509_USER) != NULL) {
+ krb5int_find_pa_data(kdc_context, request->padata,
+ KRB5_PADATA_S4U_X509_USER) != NULL) {
errcode = kdc_make_s4u2self_rep(kdc_context,
subkey,
header_ticket->enc_part2->session,
@@ -987,6 +996,7 @@ prepare_error_tgs (struct kdc_request_state *state,
krb5_error errpkt;
krb5_error_code retval = 0;
krb5_data *scratch, *e_data_asn1 = NULL, *fast_edata = NULL;
+ kdc_realm_t *kdc_active_realm = state->realm_data;
errpkt.ctime = request->nonce;
errpkt.cusec = 0;
@@ -1050,12 +1060,14 @@ prepare_error_tgs (struct kdc_request_state *state,
* some intermediate realm.
*/
static krb5_error_code
-find_alternate_tgs(krb5_kdc_req *request, krb5_db_entry **server_ptr)
+find_alternate_tgs(struct kdc_request_state *state,
+ krb5_kdc_req *request, krb5_db_entry **server_ptr)
{
krb5_error_code retval;
krb5_principal *plist = NULL, *pl2, tmpprinc;
krb5_data tmp;
krb5_db_entry *server = NULL;
+ kdc_realm_t *kdc_active_realm = state->realm_data;
*server_ptr = NULL;
@@ -1100,7 +1112,7 @@ find_alternate_tgs(krb5_kdc_req *request, krb5_db_entry **server_ptr)
krb5_free_principal(kdc_context, request->server);
request->server = tmpprinc;
- log_tgs_alt_tgt(request->server);
+ log_tgs_alt_tgt(kdc_context, request->server);
*server_ptr = server;
server = NULL;
goto cleanup;
@@ -1114,12 +1126,14 @@ cleanup:
}
static krb5_int32
-prep_reprocess_req(krb5_kdc_req *request, krb5_principal *krbtgt_princ)
+prep_reprocess_req(struct kdc_request_state *state, krb5_kdc_req *request,
+ krb5_principal *krbtgt_princ)
{
krb5_error_code retval = KRB5KRB_AP_ERR_BADMATCH;
char **realms, **cpp, *temp_buf=NULL;
krb5_data *comp1 = NULL, *comp2 = NULL;
char *comp1_str = NULL;
+ kdc_realm_t *kdc_active_realm = state->realm_data;
/* By now we know that server principal name is unknown.
* If CANONICALIZE flag is set in the request
diff --git a/src/kdc/extern.c b/src/kdc/extern.c
index 7307bfc..fe62749 100644
--- a/src/kdc/extern.c
+++ b/src/kdc/extern.c
@@ -31,11 +31,11 @@
#include "k5-int.h"
#include "kdb.h"
#include "extern.h"
+#include "realm_data.h"
/* real declarations of KDC's externs */
kdc_realm_t **kdc_realmlist = (kdc_realm_t **) NULL;
int kdc_numrealms = 0;
-kdc_realm_t *kdc_active_realm = (kdc_realm_t *) NULL;
krb5_data empty_string = {0, 0, ""};
krb5_timestamp kdc_infinity = KRB5_INT32_MAX; /* XXX */
krb5_keyblock psr_key;
diff --git a/src/kdc/extern.h b/src/kdc/extern.h
index c601e57..7dc658f 100644
--- a/src/kdc/extern.h
+++ b/src/kdc/extern.h
@@ -26,74 +26,6 @@
#ifndef __KRB5_KDC_EXTERN__
#define __KRB5_KDC_EXTERN__
-typedef struct __kdc_realm_data {
- /*
- * General Kerberos per-realm data.
- */
- char * realm_name; /* Realm name */
-/* XXX the real context should go away once the db_context is done.
- * The db_context is then associated with the realm keytab using
- * krb5_ktkdb_resolv(). There should be nothing in the context which
- * cannot span multiple realms -- proven */
- krb5_context realm_context; /* Context to be used for realm */
- krb5_keytab realm_keytab; /* keytab to be used for this realm */
- char * realm_profile; /* Profile file for this realm */
- char * realm_host_based_services; /* do referral processing for these services
- * If '*' - allow all referrals */
- char * realm_no_host_referral; /* no referral for these services.
- * If '*' - disallow all referrals and
- * ignore realm_host_based_services */
- /*
- * Database per-realm data.
- */
- char * realm_stash; /* Stash file name for realm */
- char * realm_mpname; /* Master principal name for realm */
- krb5_principal realm_mprinc; /* Master principal for realm */
- /*
- * Note realm_mkey is mkey read from stash or keyboard and may not be the
- * latest.
- */
- krb5_keyblock realm_mkey; /* Master key for this realm */
- /*
- * TGS per-realm data.
- */
- krb5_principal realm_tgsprinc; /* TGS principal for this realm */
- /*
- * Other per-realm data.
- */
- char *realm_ports; /* Per-realm KDC UDP port */
- char *realm_tcp_ports; /* Per-realm KDC TCP port */
- /*
- * Per-realm parameters.
- */
- krb5_deltat realm_maxlife; /* Maximum ticket life for realm */
- krb5_deltat realm_maxrlife; /* Maximum renewable life for realm */
- krb5_boolean realm_reject_bad_transit; /* Accept unverifiable transited_realm ? */
- krb5_boolean realm_restrict_anon; /* Anon to local TGT only */
- krb5_boolean realm_assume_des_crc_sess; /* Assume princs support des-cbc-crc for session keys */
-} kdc_realm_t;
-
-extern kdc_realm_t **kdc_realmlist;
-extern int kdc_numrealms;
-extern kdc_realm_t *kdc_active_realm;
-
-kdc_realm_t *find_realm_data (char *, krb5_ui_4);
-
-/*
- * Replace previously used global variables with the active (e.g. request's)
- * realm data. This allows us to support multiple realms with minimal logic
- * changes.
- */
-#define kdc_context kdc_active_realm->realm_context
-#define max_life_for_realm kdc_active_realm->realm_maxlife
-#define max_renewable_life_for_realm kdc_active_realm->realm_maxrlife
-#define master_keyblock kdc_active_realm->realm_mkey
-#define master_princ kdc_active_realm->realm_mprinc
-#define tgs_server kdc_active_realm->realm_tgsprinc
-#define reject_bad_transit kdc_active_realm->realm_reject_bad_transit
-#define restrict_anon kdc_active_realm->realm_restrict_anon
-#define assume_des_crc_sess kdc_active_realm->realm_assume_des_crc_sess
-
/* various externs for KDC */
extern krb5_data empty_string; /* an empty string */
extern krb5_timestamp kdc_infinity; /* greater than all other timestamps */
diff --git a/src/kdc/fast_util.c b/src/kdc/fast_util.c
index f3e037d..1ce27d6 100644
--- a/src/kdc/fast_util.c
+++ b/src/kdc/fast_util.c
@@ -46,6 +46,7 @@ static krb5_error_code armor_ap_request
krb5_auth_context authcontext = NULL;
krb5_ticket *ticket = NULL;
krb5_keyblock *subkey = NULL;
+ kdc_realm_t *kdc_active_realm = state->realm_data;
assert(armor->armor_type == KRB5_FAST_ARMOR_AP_REQUEST);
krb5_clear_error_message(kdc_context);
@@ -103,6 +104,8 @@ encrypt_fast_reply(struct kdc_request_state *state,
krb5_error_code retval = 0;
krb5_enc_data encrypted_reply;
krb5_data *encoded_response = NULL;
+ kdc_realm_t *kdc_active_realm = state->realm_data;
+
assert(state->armor_key);
retval = encode_krb5_fast_response(response, &encoded_response);
if (retval== 0)
@@ -138,14 +141,15 @@ kdc_find_fast(krb5_kdc_req **requestptr,
krb5_checksum *cksum;
krb5_boolean cksum_valid;
krb5_keyblock empty_keyblock;
+ kdc_realm_t *kdc_active_realm = state->realm_data;
if (inner_body_out != NULL)
*inner_body_out = NULL;
scratch.data = NULL;
krb5_clear_error_message(kdc_context);
memset(&empty_keyblock, 0, sizeof(krb5_keyblock));
- fast_padata = find_pa_data(request->padata,
- KRB5_PADATA_FX_FAST);
+ fast_padata = krb5int_find_pa_data(kdc_context,
+ request->padata, KRB5_PADATA_FX_FAST);
if (fast_padata != NULL){
scratch.length = fast_padata->length;
scratch.data = (char *) fast_padata->contents;
@@ -230,8 +234,9 @@ kdc_find_fast(krb5_kdc_req **requestptr,
retval = KRB5KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTION;
}
if (retval == 0)
- cookie_padata = find_pa_data(fast_req->req_body->padata,
- KRB5_PADATA_FX_COOKIE);
+ cookie_padata = krb5int_find_pa_data(kdc_context,
+ fast_req->req_body->padata,
+ KRB5_PADATA_FX_COOKIE);
if (retval == 0) {
state->fast_options = fast_req->fast_options;
krb5_free_kdc_req( kdc_context, request);
@@ -239,7 +244,11 @@ kdc_find_fast(krb5_kdc_req **requestptr,
fast_req->req_body = NULL;
}
}
- else cookie_padata = find_pa_data(request->padata, KRB5_PADATA_FX_COOKIE);
+ else {
+ cookie_padata = krb5int_find_pa_data(kdc_context,
+ request->padata,
+ KRB5_PADATA_FX_COOKIE);
+ }
if (retval == 0 && cookie_padata != NULL) {
krb5_pa_data *new_padata = malloc(sizeof (krb5_pa_data));
if (new_padata == NULL) {
@@ -272,12 +281,13 @@ kdc_find_fast(krb5_kdc_req **requestptr,
krb5_error_code
-kdc_make_rstate(struct kdc_request_state **out)
+kdc_make_rstate(kdc_realm_t *active_realm, struct kdc_request_state **out)
{
struct kdc_request_state *state = malloc( sizeof(struct kdc_request_state));
if (state == NULL)
return ENOMEM;
memset( state, 0, sizeof(struct kdc_request_state));
+ state->realm_data = active_realm;
*out = state;
return 0;
}
@@ -285,6 +295,8 @@ kdc_make_rstate(struct kdc_request_state **out)
void
kdc_free_rstate (struct kdc_request_state *s)
{
+ kdc_realm_t *kdc_active_realm = s->realm_data;
+
if (s == NULL)
return;
if (s->armor_key)
@@ -312,6 +324,7 @@ kdc_fast_response_handle_padata(struct kdc_request_state *state,
krb5_cksumtype cksumtype = CKSUMTYPE_RSA_MD5;
krb5_pa_data *empty_padata[] = {NULL};
krb5_keyblock *strengthen_key = NULL;
+ kdc_realm_t *kdc_active_realm = state->realm_data;
if (!state->armor_key)
return 0;
@@ -401,6 +414,7 @@ kdc_fast_handle_error(krb5_context context,
krb5_pa_data *outer_pa[3], *cookie = NULL;
krb5_pa_data **inner_pa = NULL;
size_t size = 0;
+ kdc_realm_t *kdc_active_realm = state->realm_data;
*fast_edata_out = NULL;
memset(outer_pa, 0, sizeof(outer_pa));
@@ -424,7 +438,8 @@ kdc_fast_handle_error(krb5_context context,
pa[0].length = encoded_fx_error->length;
pa[0].contents = (unsigned char *) encoded_fx_error->data;
inner_pa[size++] = &pa[0];
- if (find_pa_data(inner_pa, KRB5_PADATA_FX_COOKIE) == NULL)
+ if (krb5int_find_pa_data(kdc_context,
+ inner_pa, KRB5_PADATA_FX_COOKIE) == NULL)
retval = kdc_preauth_get_cookie(state, &cookie);
}
if (cookie != NULL)
@@ -464,6 +479,8 @@ kdc_fast_handle_reply_key(struct kdc_request_state *state,
krb5_keyblock **out_key)
{
krb5_error_code retval = 0;
+ kdc_realm_t *kdc_active_realm = state->realm_data;
+
if (state->armor_key)
retval = krb5_c_fx_cf2_simple(kdc_context,
state->strengthen_key, "strengthenkey",
@@ -481,6 +498,7 @@ kdc_preauth_get_cookie(struct kdc_request_state *state,
{
char *contents;
krb5_pa_data *pa = NULL;
+
/* In our current implementation, the only purpose served by
* returning a cookie is to indicate that a conversation should
* continue on error. Thus, the cookie can have a constant
diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
index 5ca3676..19998d8 100644
--- a/src/kdc/kdc_preauth.c
+++ b/src/kdc/kdc_preauth.c
@@ -269,23 +269,23 @@ cleanup:
/* Make a list of realm names. The caller should free the list container but
* not the list elements (which are aliases into kdc_realmlist). */
static krb5_error_code
-get_realm_names(const char ***list_out)
+get_realm_names(struct server_handle *handle, const char ***list_out)
{
const char **list;
int i;
- list = calloc(kdc_numrealms + 1, sizeof(*list));
+ list = calloc(handle->kdc_numrealms + 1, sizeof(*list));
if (list == NULL)
return ENOMEM;
- for (i = 0; i < kdc_numrealms; i++)
- list[i] = kdc_realmlist[i]->realm_name;
+ for (i = 0; i < handle->kdc_numrealms; i++)
+ list[i] = handle->kdc_realmlist[i]->realm_name;
list[i] = NULL;
*list_out = list;
return 0;
}
void
-load_preauth_plugins(krb5_context context)
+load_preauth_plugins(struct server_handle *handle, krb5_context context)
{
krb5_error_code ret;
struct krb5_kdcpreauth_vtable_st *vtables = NULL, *vt;
@@ -303,7 +303,7 @@ load_preauth_plugins(krb5_context context)
if (preauth_systems == NULL)
goto cleanup;
- if (get_realm_names(&realm_names))
+ if (get_realm_names(handle, &realm_names))
goto cleanup;
/* Add the static system to the list first. No static systems require
@@ -718,6 +718,7 @@ hint_list_finish(struct hint_state *state, krb5_error_code code)
{
kdc_hint_respond_fn oldrespond = state->respond;
void *oldarg = state->arg;
+ kdc_realm_t *kdc_active_realm = state->realm;
if (!code) {
if (state->pa_data[0] == 0) {
@@ -746,7 +747,6 @@ finish_get_edata(void *arg, krb5_error_code code, krb5_pa_data *pa)
{
struct hint_state *state = arg;
- kdc_active_realm = state->realm;
if (code == 0) {
if (pa == NULL) {
/* Include an empty value of the current type. */
@@ -765,6 +765,7 @@ static void
hint_list_next(struct hint_state *state)
{
preauth_system *ap = state->ap;
+ kdc_realm_t *kdc_active_realm = state->realm;
if (ap->type == -1) {
hint_list_finish(state, 0);
@@ -810,7 +811,7 @@ get_preauth_hint_list(krb5_kdc_req *request, krb5_kdcpreauth_rock rock,
state->arg = arg;
state->request = request;
state->rock = rock;
- state->realm = kdc_active_realm;
+ state->realm = rock->rstate->realm_data;
state->e_data_out = e_data_out;
/* Allocate two extra entries for the cookie and the terminator. */
@@ -986,7 +987,6 @@ finish_verify_padata(void *arg, krb5_error_code code,
krb5_boolean typed_e_data_flag;
assert(state);
- kdc_active_realm = state->realm; /* Restore the realm. */
*state->modreq_ptr = modreq;
if (code) {
@@ -1135,7 +1135,7 @@ check_padata(krb5_context context, krb5_kdcpreauth_rock rock,
state->padata_context = padata_context;
state->e_data_out = e_data;
state->typed_e_data_out = typed_e_data;
- state->realm = kdc_active_realm;
+ state->realm = rock->rstate->realm_data;
#ifdef DEBUG
krb5_klog_syslog (LOG_DEBUG, "checking padata");
@@ -1663,7 +1663,7 @@ return_enc_padata(krb5_context context, krb5_data *req_pkt,
if (code)
return code;
}
- code = kdc_handle_protected_negotiation(req_pkt, request, reply_key,
+ code = kdc_handle_protected_negotiation(context, req_pkt, request, reply_key,
&reply_encpart->enc_padata);
if (code)
goto cleanup;
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index 4f6ce6f..773d8cf 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -68,12 +68,14 @@ const int vague_errors = 1;
const int vague_errors = 0;
#endif
-static krb5_error_code kdc_rd_ap_req(krb5_ap_req *apreq,
+static krb5_error_code kdc_rd_ap_req(kdc_realm_t *kdc_active_realm,
+ krb5_ap_req *apreq,
krb5_auth_context auth_context,
krb5_db_entry **server,
krb5_keyblock **tgskey,
krb5_ticket **ticket);
-static krb5_error_code find_server_key(krb5_db_entry *, krb5_enctype,
+static krb5_error_code find_server_key(krb5_context,
+ krb5_db_entry *, krb5_enctype,
krb5_kvno, krb5_keyblock **,
krb5_kvno *);
@@ -82,7 +84,8 @@ static krb5_error_code find_server_key(krb5_db_entry *, krb5_enctype,
* The replacement should be freed with krb5_free_authdata().
*/
krb5_error_code
-concat_authorization_data(krb5_authdata **first, krb5_authdata **second,
+concat_authorization_data(krb5_context context,
+ krb5_authdata **first, krb5_authdata **second,
krb5_authdata ***output)
{
register int i, j;
@@ -106,7 +109,7 @@ concat_authorization_data(krb5_authdata **first, krb5_authdata **second,
/* now walk & copy */
retdata[i] = (krb5_authdata *)malloc(sizeof(*retdata[i]));
if (!retdata[i]) {
- krb5_free_authdata(kdc_context, retdata);
+ krb5_free_authdata(context, retdata);
return ENOMEM;
}
*retdata[i] = **ptr;
@@ -114,7 +117,7 @@ concat_authorization_data(krb5_authdata **first, krb5_authdata **second,
(krb5_octet *)malloc(retdata[i]->length))) {
free(retdata[i]);
retdata[i] = 0;
- krb5_free_authdata(kdc_context, retdata);
+ krb5_free_authdata(context, retdata);
return ENOMEM;
}
memcpy(retdata[i]->contents, (*ptr)->contents, retdata[i]->length);
@@ -127,13 +130,7 @@ concat_authorization_data(krb5_authdata **first, krb5_authdata **second,
}
krb5_boolean
-realm_compare(krb5_const_principal princ1, krb5_const_principal princ2)
-{
- return krb5_realm_compare(kdc_context, princ1, princ2);
-}
-
-krb5_boolean
-is_local_principal(krb5_const_principal princ1)
+is_local_principal(kdc_realm_t *kdc_active_realm, krb5_const_principal princ1)
{
return krb5_realm_compare(kdc_context, princ1, tgs_server);
}
@@ -197,14 +194,9 @@ comp_cksum(krb5_context kcontext, krb5_data *source, krb5_ticket *ticket,
return(0);
}
-krb5_pa_data *
-find_pa_data(krb5_pa_data **padata, krb5_preauthtype pa_type)
-{
- return krb5int_find_pa_data(kdc_context, padata, pa_type);
-}
-
krb5_error_code
-kdc_process_tgs_req(krb5_kdc_req *request, const krb5_fulladdr *from,
+kdc_process_tgs_req(kdc_realm_t *kdc_active_realm,
+ krb5_kdc_req *request, const krb5_fulladdr *from,
krb5_data *pkt, krb5_ticket **ticket,
krb5_db_entry **krbtgt_ptr,
krb5_keyblock **tgskey,
@@ -226,7 +218,8 @@ kdc_process_tgs_req(krb5_kdc_req *request, const krb5_fulladdr *from,
*krbtgt_ptr = NULL;
*tgskey = NULL;
- tmppa = find_pa_data(request->padata, KRB5_PADATA_AP_REQ);
+ tmppa = krb5int_find_pa_data(kdc_context,
+ request->padata, KRB5_PADATA_AP_REQ);
if (!tmppa)
return KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
@@ -252,7 +245,8 @@ kdc_process_tgs_req(krb5_kdc_req *request, const krb5_fulladdr *from,
we set a flag here for checking below.
*/
- foreign_server = !is_local_principal(apreq->ticket->server);
+ foreign_server = !is_local_principal(kdc_active_realm,
+ apreq->ticket->server);
if ((retval = krb5_auth_con_init(kdc_context, &auth_context)))
goto cleanup;
@@ -265,7 +259,8 @@ kdc_process_tgs_req(krb5_kdc_req *request, const krb5_fulladdr *from,
from->address)) )
goto cleanup_auth_context;
- retval = kdc_rd_ap_req(apreq, auth_context, &krbtgt, tgskey, ticket);
+ retval = kdc_rd_ap_req(kdc_active_realm,
+ apreq, auth_context, &krbtgt, tgskey, ticket);
if (retval)
goto cleanup_auth_context;
@@ -308,8 +303,10 @@ kdc_process_tgs_req(krb5_kdc_req *request, const krb5_fulladdr *from,
/* make sure the client is of proper lineage (see above) */
if (foreign_server &&
- !find_pa_data(request->padata, KRB5_PADATA_FOR_USER)) {
- if (is_local_principal((*ticket)->enc_part2->client)) {
+ !krb5int_find_pa_data(kdc_context,
+ request->padata, KRB5_PADATA_FOR_USER)) {
+ if (is_local_principal(kdc_active_realm,
+ (*ticket)->enc_part2->client)) {
/* someone in a foreign realm claiming to be local */
krb5_klog_syslog(LOG_INFO, _("PROCESS_TGS: failed lineage check"));
retval = KRB5KDC_ERR_POLICY;
@@ -369,7 +366,8 @@ cleanup:
*/
static
krb5_error_code
-kdc_rd_ap_req(krb5_ap_req *apreq, krb5_auth_context auth_context,
+kdc_rd_ap_req(kdc_realm_t *kdc_active_realm,
+ krb5_ap_req *apreq, krb5_auth_context auth_context,
krb5_db_entry **server, krb5_keyblock **tgskey,
krb5_ticket **ticket)
{
@@ -391,7 +389,8 @@ kdc_rd_ap_req(krb5_ap_req *apreq, krb5_auth_context auth_context,
match_enctype = 0;
}
- retval = kdc_get_server_key(apreq->ticket, 0, match_enctype, server, NULL,
+ retval = kdc_get_server_key(kdc_context,
+ apreq->ticket, 0, match_enctype, server, NULL,
NULL);
if (retval)
return retval;
@@ -400,7 +399,8 @@ kdc_rd_ap_req(krb5_ap_req *apreq, krb5_auth_context auth_context,
kvno = apreq->ticket->enc_part.kvno;
do {
krb5_free_keyblock(kdc_context, *tgskey);
- retval = find_server_key(*server, search_enctype, kvno, tgskey, &kvno);
+ retval = find_server_key(kdc_context,
+ *server, search_enctype, kvno, tgskey, &kvno);
if (retval)
continue;
@@ -429,7 +429,8 @@ kdc_rd_ap_req(krb5_ap_req *apreq, krb5_auth_context auth_context,
* This is also used by do_tgs_req() for u2u auth.
*/
krb5_error_code
-kdc_get_server_key(krb5_ticket *ticket, unsigned int flags,
+kdc_get_server_key(krb5_context context,
+ krb5_ticket *ticket, unsigned int flags,
krb5_boolean match_enctype, krb5_db_entry **server_ptr,
krb5_keyblock **key, krb5_kvno *kvno)
{
@@ -445,11 +446,11 @@ kdc_get_server_key(krb5_ticket *ticket, unsigned int flags,
*server_ptr = NULL;
- retval = krb5_db_get_principal(kdc_context, ticket->server, flags,
+ retval = krb5_db_get_principal(context, ticket->server, flags,
&server);
if (retval == KRB5_KDB_NOENTRY) {
char *sname;
- if (!krb5_unparse_name(kdc_context, ticket->server, &sname)) {
+ if (!krb5_unparse_name(context, ticket->server, &sname)) {
limit_string(sname);
krb5_klog_syslog(LOG_ERR,
_("TGS_REQ: UNKNOWN SERVER: server='%s'"), sname);
@@ -465,7 +466,8 @@ kdc_get_server_key(krb5_ticket *ticket, unsigned int flags,
}
if (key) {
- retval = find_server_key(server, search_enctype, search_kvno, key, kvno);
+ retval = find_server_key(context, server, search_enctype, search_kvno,
+ key, kvno);
if (retval)
goto errout;
}
@@ -474,7 +476,7 @@ kdc_get_server_key(krb5_ticket *ticket, unsigned int flags,
return 0;
errout:
- krb5_db_free_principal(kdc_context, server);
+ krb5_db_free_principal(context, server);
return retval;
}
@@ -484,7 +486,8 @@ errout:
*/
static
krb5_error_code
-find_server_key(krb5_db_entry *server, krb5_enctype enctype, krb5_kvno kvno,
+find_server_key(krb5_context context,
+ krb5_db_entry *server, krb5_enctype enctype, krb5_kvno kvno,
krb5_keyblock **key_out, krb5_kvno *kvno_out)
{
krb5_error_code retval;
@@ -492,7 +495,7 @@ find_server_key(krb5_db_entry *server, krb5_enctype enctype, krb5_kvno kvno,
krb5_keyblock * key;
*key_out = NULL;
- retval = krb5_dbe_find_enctype(kdc_context, server, enctype, -1,
+ retval = krb5_dbe_find_enctype(context, server, enctype, -1,
kvno ? (krb5_int32)kvno : -1, &server_key);
if (retval)
return retval;
@@ -500,13 +503,13 @@ find_server_key(krb5_db_entry *server, krb5_enctype enctype, krb5_kvno kvno,
return KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
if ((key = (krb5_keyblock *)malloc(sizeof *key)) == NULL)
return ENOMEM;
- retval = krb5_dbe_decrypt_key_data(kdc_context, NULL, server_key,
+ retval = krb5_dbe_decrypt_key_data(context, NULL, server_key,
key, NULL);
if (retval)
goto errout;
if (enctype != -1) {
krb5_boolean similar;
- retval = krb5_c_enctype_compare(kdc_context, enctype, key->enctype,
+ retval = krb5_c_enctype_compare(context, enctype, key->enctype,
&similar);
if (retval)
goto errout;
@@ -521,7 +524,7 @@ find_server_key(krb5_db_entry *server, krb5_enctype enctype, krb5_kvno kvno,
if (kvno_out)
*kvno_out = server_key->key_data_kvno;
errout:
- krb5_free_keyblock(kdc_context, key);
+ krb5_free_keyblock(context, key);
return retval;
}
@@ -940,14 +943,15 @@ errcode_to_protocol(krb5_error_code code)
/* Return -1 if the AS or TGS request is disallowed due to KDC policy on
* anonymous tickets. */
static int
-check_anon(krb5_context context, krb5_principal client, krb5_principal server)
+check_anon(kdc_realm_t *kdc_active_realm,
+ krb5_principal client, krb5_principal server)
{
/* If restrict_anon is set, reject requests from anonymous to principals
* other than the local TGT. */
if (restrict_anon &&
- krb5_principal_compare_any_realm(context, client,
+ krb5_principal_compare_any_realm(kdc_context, client,
krb5_anonymous_principal()) &&
- !krb5_principal_compare(context, server, tgs_server))
+ !krb5_principal_compare(kdc_context, server, tgs_server))
return -1;
return 0;
}
@@ -962,7 +966,8 @@ check_anon(krb5_context context, krb5_principal client, krb5_principal server)
KDC_OPT_VALIDATE | KDC_OPT_RENEW | \
KDC_OPT_ENC_TKT_IN_SKEY | KDC_OPT_CNAME_IN_ADDL_TKT)
int
-validate_as_request(register krb5_kdc_req *request, krb5_db_entry client,
+validate_as_request(kdc_realm_t *kdc_active_realm,
+ register krb5_kdc_req *request, krb5_db_entry client,
krb5_db_entry server, krb5_timestamp kdc_time,
const char **status, krb5_pa_data ***e_data)
{
@@ -1071,7 +1076,7 @@ validate_as_request(register krb5_kdc_req *request, krb5_db_entry client,
return(KDC_ERR_MUST_USE_USER2USER);
}
- if (check_anon(kdc_context, request->client, request->server) != 0) {
+ if (check_anon(kdc_active_realm, request->client, request->server) != 0) {
*status = "ANONYMOUS NOT ALLOWED";
return(KDC_ERR_POLICY);
}
@@ -1265,7 +1270,8 @@ fetch_asn1_field(unsigned char *astream, unsigned int level,
KDC_OPT_VALIDATE)
int
-validate_tgs_request(register krb5_kdc_req *request, krb5_db_entry server,
+validate_tgs_request(kdc_realm_t *kdc_active_realm,
+ register krb5_kdc_req *request, krb5_db_entry server,
krb5_ticket *ticket, krb5_timestamp kdc_time,
const char **status, krb5_pa_data ***e_data)
{
@@ -1498,7 +1504,7 @@ validate_tgs_request(register krb5_kdc_req *request, krb5_db_entry server,
return KRB_ERR_GENERIC;
}
- if (check_anon(kdc_context, ticket->enc_part2->client,
+ if (check_anon(kdc_active_realm, ticket->enc_part2->client,
request->server) != 0) {
*status = "ANONYMOUS NOT ALLOWED";
return(KDC_ERR_POLICY);
@@ -1522,7 +1528,7 @@ validate_tgs_request(register krb5_kdc_req *request, krb5_db_entry server,
/* Return true if we believe server can support enctype as a session key. */
static krb5_boolean
-dbentry_supports_enctype(krb5_context context, krb5_db_entry *server,
+dbentry_supports_enctype(kdc_realm_t *kdc_active_realm, krb5_db_entry *server,
krb5_enctype enctype)
{
krb5_error_code retval;
@@ -1533,11 +1539,12 @@ dbentry_supports_enctype(krb5_context context, krb5_db_entry *server,
krb5_boolean in_list;
/* Look up the supported session key enctypes list in the KDB. */
- retval = krb5_dbe_get_string(context, server, KRB5_KDB_SK_SESSION_ENCTYPES,
+ retval = krb5_dbe_get_string(kdc_context, server,
+ KRB5_KDB_SK_SESSION_ENCTYPES,
&etypes_str);
if (retval == 0 && etypes_str != NULL && *etypes_str != '\0') {
/* Pass a fake profile key for tracing of unrecognized tokens. */
- retval = krb5int_parse_enctype_list(context, "KDB-session_etypes",
+ retval = krb5int_parse_enctype_list(kdc_context, "KDB-session_etypes",
etypes_str, default_enctypes,
&etypes);
if (retval == 0 && etypes != NULL && etypes[0]) {
@@ -1562,7 +1569,7 @@ dbentry_supports_enctype(krb5_context context, krb5_db_entry *server,
return FALSE;
/* Assume the server supports any enctype it has a long-term key for. */
- return !krb5_dbe_find_enctype(context, server, enctype, -1, 0, &datap);
+ return !krb5_dbe_find_enctype(kdc_context, server, enctype, -1, 0, &datap);
}
/*
@@ -1571,7 +1578,7 @@ dbentry_supports_enctype(krb5_context context, krb5_db_entry *server,
* requested, and what the KDC and the application server can support.
*/
krb5_enctype
-select_session_keytype(krb5_context context, krb5_db_entry *server,
+select_session_keytype(kdc_realm_t *kdc_active_realm, krb5_db_entry *server,
int nktypes, krb5_enctype *ktype)
{
int i;
@@ -1580,10 +1587,10 @@ select_session_keytype(krb5_context context, krb5_db_entry *server,
if (!krb5_c_valid_enctype(ktype[i]))
continue;
- if (!krb5_is_permitted_enctype(context, ktype[i]))
+ if (!krb5_is_permitted_enctype(kdc_context, ktype[i]))
continue;
- if (dbentry_supports_enctype(context, server, ktype[i]))
+ if (dbentry_supports_enctype(kdc_active_realm, server, ktype[i]))
return ktype[i];
}
@@ -1765,7 +1772,7 @@ verify_for_user_checksum(krb5_context context,
* Legacy protocol transition (Windows 2003 and above)
*/
static krb5_error_code
-kdc_process_for_user(krb5_context context,
+kdc_process_for_user(kdc_realm_t *kdc_active_realm,
krb5_pa_data *pa_data,
krb5_keyblock *tgs_session,
krb5_pa_s4u_x509_user **s4u_x509_user,
@@ -1782,7 +1789,7 @@ kdc_process_for_user(krb5_context context,
if (code)
return code;
- code = verify_for_user_checksum(context, tgs_session, for_user);
+ code = verify_for_user_checksum(kdc_context, tgs_session, for_user);
if (code) {
*status = "INVALID_S4U2SELF_CHECKSUM";
krb5_free_pa_for_user(kdc_context, for_user);
@@ -1797,7 +1804,7 @@ kdc_process_for_user(krb5_context context,
(*s4u_x509_user)->user_id.user = for_user->user;
for_user->user = NULL;
- krb5_free_pa_for_user(context, for_user);
+ krb5_free_pa_for_user(kdc_context, for_user);
return 0;
}
@@ -2008,7 +2015,7 @@ cleanup:
* Protocol transition (S4U2Self)
*/
krb5_error_code
-kdc_process_s4u2self_req(krb5_context context,
+kdc_process_s4u2self_req(kdc_realm_t *kdc_active_realm,
krb5_kdc_req *request,
krb5_const_principal client_princ,
const krb5_db_entry *server,
@@ -2026,9 +2033,10 @@ kdc_process_s4u2self_req(krb5_context context,
*princ_ptr = NULL;
- pa_data = find_pa_data(request->padata, KRB5_PADATA_S4U_X509_USER);
+ pa_data = krb5int_find_pa_data(kdc_context,
+ request->padata, KRB5_PADATA_S4U_X509_USER);
if (pa_data != NULL) {
- code = kdc_process_s4u_x509_user(context,
+ code = kdc_process_s4u_x509_user(kdc_context,
request,
pa_data,
tgs_subkey,
@@ -2038,9 +2046,10 @@ kdc_process_s4u2self_req(krb5_context context,
if (code != 0)
return code;
} else {
- pa_data = find_pa_data(request->padata, KRB5_PADATA_FOR_USER);
+ pa_data = krb5int_find_pa_data(kdc_context,
+ request->padata, KRB5_PADATA_FOR_USER);
if (pa_data != NULL) {
- code = kdc_process_for_user(context,
+ code = kdc_process_for_user(kdc_active_realm,
pa_data,
tgs_session,
s4u_x509_user,
@@ -2078,9 +2087,9 @@ kdc_process_s4u2self_req(krb5_context context,
* the TGT and that we have a global name service.
*/
flags = 0;
- switch (krb5_princ_type(context, request->server)) {
+ switch (krb5_princ_type(kdc_context, request->server)) {
case KRB5_NT_SRV_HST: /* (1) */
- if (krb5_princ_size(context, request->server) == 2)
+ if (krb5_princ_size(kdc_context, request->server) == 2)
flags |= KRB5_PRINCIPAL_COMPARE_IGNORE_REALM;
break;
case KRB5_NT_ENTERPRISE_PRINCIPAL: /* (2) */
@@ -2090,7 +2099,7 @@ kdc_process_s4u2self_req(krb5_context context,
break;
}
- if (!krb5_principal_compare_flags(context,
+ if (!krb5_principal_compare_flags(kdc_context,
request->server,
client_princ,
flags)) {
@@ -2114,11 +2123,13 @@ kdc_process_s4u2self_req(krb5_context context,
/*
* Do not attempt to lookup principals in foreign realms.
*/
- if (is_local_principal((*s4u_x509_user)->user_id.user)) {
+ if (is_local_principal(kdc_active_realm,
+ (*s4u_x509_user)->user_id.user)) {
krb5_db_entry no_server;
krb5_pa_data **e_data = NULL;
- code = krb5_db_get_principal(context, (*s4u_x509_user)->user_id.user,
+ code = krb5_db_get_principal(kdc_context,
+ (*s4u_x509_user)->user_id.user,
KRB5_KDB_FLAG_INCLUDE_PAC, &princ);
if (code == KRB5_KDB_NOENTRY) {
*status = "UNKNOWN_S4U2SELF_PRINCIPAL";
@@ -2130,11 +2141,11 @@ kdc_process_s4u2self_req(krb5_context context,
memset(&no_server, 0, sizeof(no_server));
- code = validate_as_request(request, *princ,
+ code = validate_as_request(kdc_active_realm, request, *princ,
no_server, kdc_time, status, &e_data);
if (code) {
- krb5_db_free_principal(context, princ);
- krb5_free_pa_data(context, e_data);
+ krb5_db_free_principal(kdc_context, princ);
+ krb5_free_pa_data(kdc_context, e_data);
return code;
}
@@ -2161,7 +2172,7 @@ check_allowed_to_delegate_to(krb5_context context, krb5_const_principal client,
}
krb5_error_code
-kdc_process_s4u2proxy_req(krb5_context context,
+kdc_process_s4u2proxy_req(kdc_realm_t *kdc_active_realm,
krb5_kdc_req *request,
const krb5_enc_tkt_part *t2enc,
const krb5_db_entry *server,
@@ -2206,7 +2217,7 @@ kdc_process_s4u2proxy_req(krb5_context context,
}
krb5_error_code
-kdc_check_transited_list(krb5_context context,
+kdc_check_transited_list(kdc_realm_t *kdc_active_realm,
const krb5_data *trans,
const krb5_data *realm1,
const krb5_data *realm2)
@@ -2219,7 +2230,7 @@ kdc_check_transited_list(krb5_context context,
return code;
/* Check against the KDB module. */
- code = krb5_db_check_transited_realms(context, trans, realm1, realm2);
+ code = krb5_db_check_transited_realms(kdc_context, trans, realm1, realm2);
if (code == KRB5_PLUGIN_OP_NOTSUPP)
code = 0;
return code;
@@ -2258,7 +2269,7 @@ validate_transit_path(krb5_context context,
/* Someday, pass local address/port as well. */
/* Currently no info about name canonicalization is logged. */
void
-log_as_req(const krb5_fulladdr *from,
+log_as_req(krb5_context context, const krb5_fulladdr *from,
krb5_kdc_req *request, krb5_kdc_rep *reply,
krb5_db_entry *client, const char *cname,
krb5_db_entry *server, const char *sname,
@@ -2293,7 +2304,7 @@ log_as_req(const krb5_fulladdr *from,
ktypestr, fromstring, status,
cname2, sname2, emsg ? ", " : "", emsg ? emsg : "");
}
- krb5_db_audit_as_req(kdc_context, request, client, server, authtime,
+ krb5_db_audit_as_req(context, request, client, server, authtime,
errcode);
#if 0
/* Sun (OpenSolaris) version would probably something like this.
@@ -2369,10 +2380,10 @@ log_tgs_req(const krb5_fulladdr *from,
}
void
-log_tgs_alt_tgt(krb5_principal p)
+log_tgs_alt_tgt(krb5_context context, krb5_principal p)
{
char *sname;
- if (krb5_unparse_name(kdc_context, p, &sname)) {
+ if (krb5_unparse_name(context, p, &sname)) {
krb5_klog_syslog(LOG_INFO,
_("TGS_REQ: issuing alternate <un-unparseable> TGT"));
} else {
@@ -2444,7 +2455,7 @@ add_pa_data_element(krb5_context context,
}
void
-kdc_get_ticket_endtime(krb5_context context,
+kdc_get_ticket_endtime(kdc_realm_t *kdc_active_realm,
krb5_timestamp starttime,
krb5_timestamp endtime,
krb5_timestamp till,
@@ -2480,7 +2491,8 @@ kdc_get_ticket_endtime(krb5_context context,
* @param index in/out index into @c out_enc_padata for next item
*/
krb5_error_code
-kdc_handle_protected_negotiation(krb5_data *req_pkt, krb5_kdc_req *request,
+kdc_handle_protected_negotiation(krb5_context context,
+ krb5_data *req_pkt, krb5_kdc_req *request,
const krb5_keyblock *reply_key,
krb5_pa_data ***out_enc_padata)
{
@@ -2488,14 +2500,14 @@ kdc_handle_protected_negotiation(krb5_data *req_pkt, krb5_kdc_req *request,
krb5_checksum checksum;
krb5_data *out = NULL;
krb5_pa_data pa, *pa_in;
- pa_in = krb5int_find_pa_data(kdc_context, request->padata,
+ pa_in = krb5int_find_pa_data(context, request->padata,
KRB5_ENCPADATA_REQ_ENC_PA_REP);
if (pa_in == NULL)
return 0;
pa.magic = KV5M_PA_DATA;
pa.pa_type = KRB5_ENCPADATA_REQ_ENC_PA_REP;
memset(&checksum, 0, sizeof(checksum));
- retval = krb5_c_make_checksum(kdc_context,0, reply_key,
+ retval = krb5_c_make_checksum(context,0, reply_key,
KRB5_KEYUSAGE_AS_REQ, req_pkt, &checksum);
if (retval != 0)
goto cleanup;
@@ -2504,7 +2516,7 @@ kdc_handle_protected_negotiation(krb5_data *req_pkt, krb5_kdc_req *request,
goto cleanup;
pa.contents = (krb5_octet *) out->data;
pa.length = out->length;
- retval = add_pa_data_element(kdc_context, &pa, out_enc_padata, FALSE);
+ retval = add_pa_data_element(context, &pa, out_enc_padata, FALSE);
if (retval)
goto cleanup;
out->data = NULL;
@@ -2512,12 +2524,12 @@ kdc_handle_protected_negotiation(krb5_data *req_pkt, krb5_kdc_req *request,
pa.pa_type = KRB5_PADATA_FX_FAST;
pa.length = 0;
pa.contents = NULL;
- retval = add_pa_data_element(kdc_context, &pa, out_enc_padata, FALSE);
+ retval = add_pa_data_element(context, &pa, out_enc_padata, FALSE);
cleanup:
if (checksum.contents)
- krb5_free_checksum_contents(kdc_context, &checksum);
+ krb5_free_checksum_contents(context, &checksum);
if (out != NULL)
- krb5_free_data(kdc_context, out);
+ krb5_free_data(context, out);
return retval;
}
@@ -2590,12 +2602,14 @@ make_toolong_error (void *handle, krb5_data **out)
krb5_error errpkt;
krb5_error_code retval;
krb5_data *scratch;
+ struct server_handle *h = handle;
- retval = krb5_us_timeofday(kdc_context, &errpkt.stime, &errpkt.susec);
+ retval = krb5_us_timeofday(h->kdc_err_context,
+ &errpkt.stime, &errpkt.susec);
if (retval)
return retval;
errpkt.error = KRB_ERR_FIELD_TOOLONG;
- errpkt.server = tgs_server;
+ errpkt.server = h->kdc_realmlist[0]->realm_tgsprinc;
errpkt.client = NULL;
errpkt.cusec = 0;
errpkt.ctime = 0;
@@ -2606,7 +2620,7 @@ make_toolong_error (void *handle, krb5_data **out)
scratch = malloc(sizeof(*scratch));
if (scratch == NULL)
return ENOMEM;
- retval = krb5_mk_error(kdc_context, &errpkt, scratch);
+ retval = krb5_mk_error(h->kdc_err_context, &errpkt, scratch);
if (retval) {
free(scratch);
return retval;
@@ -2616,15 +2630,11 @@ make_toolong_error (void *handle, krb5_data **out)
return 0;
}
-krb5_context get_context(void *handle)
-{
- return kdc_context;
-}
-
-void reset_for_hangup()
+void reset_for_hangup(void *ctx)
{
int k;
+ struct server_handle *h = ctx;
- for (k = 0; k < kdc_numrealms; k++)
- krb5_db_refresh_config(kdc_realmlist[k]->realm_context);
+ for (k = 0; k < h->kdc_numrealms; k++)
+ krb5_db_refresh_config(h->kdc_realmlist[k]->realm_context);
}
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index 0cd7989..2f215a7 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -32,10 +32,12 @@
#include "kdb.h"
#include "net-server.h"
+#include "realm_data.h"
+#include "reqstate.h"
krb5_error_code check_hot_list (krb5_ticket *);
-krb5_boolean realm_compare (krb5_const_principal, krb5_const_principal);
-krb5_boolean is_local_principal(krb5_const_principal princ1);
+krb5_boolean is_local_principal(kdc_realm_t *kdc_active_realm,
+ krb5_const_principal princ1);
krb5_boolean krb5_is_tgs_principal (krb5_const_principal);
krb5_boolean is_cross_tgs_principal(krb5_const_principal);
krb5_error_code
@@ -49,7 +51,8 @@ compress_transited (krb5_data *,
krb5_principal,
krb5_data *);
krb5_error_code
-concat_authorization_data (krb5_authdata **,
+concat_authorization_data (krb5_context,
+ krb5_authdata **,
krb5_authdata **,
krb5_authdata ***);
krb5_error_code
@@ -58,7 +61,7 @@ fetch_last_req_info (krb5_db_entry *, krb5_last_req_entry ***);
krb5_error_code
kdc_convert_key (krb5_keyblock *, krb5_keyblock *, int);
krb5_error_code
-kdc_process_tgs_req (krb5_kdc_req *,
+kdc_process_tgs_req (kdc_realm_t *, krb5_kdc_req *,
const krb5_fulladdr *,
krb5_data *,
krb5_ticket **,
@@ -67,12 +70,12 @@ kdc_process_tgs_req (krb5_kdc_req *,
krb5_pa_data **pa_tgs_req);
krb5_error_code
-kdc_get_server_key (krb5_ticket *, unsigned int,
+kdc_get_server_key (krb5_context, krb5_ticket *, unsigned int,
krb5_boolean match_enctype,
krb5_db_entry **, krb5_keyblock **, krb5_kvno *);
int
-validate_as_request (krb5_kdc_req *, krb5_db_entry,
+validate_as_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry,
krb5_db_entry, krb5_timestamp,
const char **, krb5_pa_data ***);
@@ -82,7 +85,7 @@ validate_forwardable(krb5_kdc_req *, krb5_db_entry,
const char **);
int
-validate_tgs_request (krb5_kdc_req *, krb5_db_entry,
+validate_tgs_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry,
krb5_ticket *, krb5_timestamp,
const char **, krb5_pa_data ***);
@@ -90,7 +93,7 @@ int
fetch_asn1_field (unsigned char *, unsigned int, unsigned int, krb5_data *);
krb5_enctype
-select_session_keytype (krb5_context context,
+select_session_keytype (kdc_realm_t *kdc_active_realm,
krb5_db_entry *server,
int nktypes,
krb5_enctype *ktypes);
@@ -106,12 +109,12 @@ rep_etypes2str(char *s, size_t len, krb5_kdc_rep *rep);
/* do_as_req.c */
void
process_as_req (krb5_kdc_req *, krb5_data *,
- const krb5_fulladdr *,
+ const krb5_fulladdr *, kdc_realm_t *,
verto_ctx *, loop_respond_fn, void *);
/* do_tgs_req.c */
krb5_error_code
-process_tgs_req (krb5_data *,
+process_tgs_req (struct server_handle *, krb5_data *,
const krb5_fulladdr *,
krb5_data ** );
/* dispatch.c */
@@ -125,8 +128,6 @@ dispatch (void *,
loop_respond_fn,
void *);
-krb5_error_code
-setup_server_realm (krb5_principal);
void
kdc_err(krb5_context call_context, errcode_t code, const char *fmt, ...)
#if !defined(__cplusplus) && (__GNUC__ > 2)
@@ -159,7 +160,7 @@ get_preauth_hint_list(krb5_kdc_req *request,
krb5_kdcpreauth_rock rock, krb5_pa_data ***e_data_out,
kdc_hint_respond_fn respond, void *arg);
void
-load_preauth_plugins(krb5_context context);
+load_preauth_plugins(struct server_handle * handle, krb5_context context);
void
unload_preauth_plugins(krb5_context context);
@@ -180,9 +181,6 @@ return_padata(krb5_context context, krb5_kdcpreauth_rock rock,
void
free_padata_context(krb5_context context, void *padata_context);
-krb5_pa_data *
-find_pa_data (krb5_pa_data **padata, krb5_preauthtype pa_type);
-
krb5_error_code
add_pa_data_element (krb5_context context,
krb5_pa_data *padata,
@@ -222,13 +220,13 @@ handle_authdata (krb5_context context,
/* replay.c */
krb5_error_code kdc_init_lookaside(krb5_context context);
-krb5_boolean kdc_check_lookaside (krb5_data *, krb5_data **);
-void kdc_insert_lookaside (krb5_data *, krb5_data *);
+krb5_boolean kdc_check_lookaside (krb5_context, krb5_data *, krb5_data **);
+void kdc_insert_lookaside (krb5_context, krb5_data *, krb5_data *);
void kdc_remove_lookaside (krb5_context kcontext, krb5_data *);
void kdc_free_lookaside(krb5_context);
/* kdc_util.c */
-void reset_for_hangup(void);
+void reset_for_hangup(void *);
krb5_boolean
include_pac_p(krb5_context context, krb5_kdc_req *request);
@@ -242,7 +240,7 @@ return_enc_padata(krb5_context context,
krb5_boolean is_referral);
krb5_error_code
-kdc_process_s4u2self_req (krb5_context context,
+kdc_process_s4u2self_req (kdc_realm_t *kdc_active_realm,
krb5_kdc_req *request,
krb5_const_principal client_princ,
const krb5_db_entry *server,
@@ -262,7 +260,7 @@ kdc_make_s4u2self_rep (krb5_context context,
krb5_enc_kdc_rep_part *reply_encpart);
krb5_error_code
-kdc_process_s4u2proxy_req (krb5_context context,
+kdc_process_s4u2proxy_req (kdc_realm_t *kdc_active_realm,
krb5_kdc_req *request,
const krb5_enc_tkt_part *t2enc,
const krb5_db_entry *server,
@@ -271,7 +269,7 @@ kdc_process_s4u2proxy_req (krb5_context context,
const char **status);
krb5_error_code
-kdc_check_transited_list (krb5_context context,
+kdc_check_transited_list (kdc_realm_t *kdc_active_realm,
const krb5_data *trans,
const krb5_data *realm1,
const krb5_data *realm2);
@@ -296,7 +294,7 @@ validate_transit_path(krb5_context context,
krb5_db_entry *server,
krb5_db_entry *krbtgt);
void
-kdc_get_ticket_endtime(krb5_context context,
+kdc_get_ticket_endtime(kdc_realm_t *kdc_active_realm,
krb5_timestamp now,
krb5_timestamp endtime,
krb5_timestamp till,
@@ -305,7 +303,7 @@ kdc_get_ticket_endtime(krb5_context context,
krb5_timestamp *out_endtime);
void
-log_as_req(const krb5_fulladdr *from,
+log_as_req(krb5_context context, const krb5_fulladdr *from,
krb5_kdc_req *request, krb5_kdc_rep *reply,
krb5_db_entry *client, const char *cname,
krb5_db_entry *server, const char *sname,
@@ -319,20 +317,7 @@ log_tgs_req(const krb5_fulladdr *from,
unsigned int c_flags, const char *s4u_name,
const char *status, krb5_error_code errcode, const char *emsg);
void
-log_tgs_alt_tgt(krb5_principal p);
-
-/*Request state*/
-
-struct kdc_request_state {
- krb5_keyblock *armor_key;
- krb5_keyblock *strengthen_key;
- krb5_pa_data *cookie;
- krb5_int32 fast_options;
- krb5_int32 fast_internal_flags;
-};
-
-krb5_error_code kdc_make_rstate(struct kdc_request_state **out);
-void kdc_free_rstate (struct kdc_request_state *s);
+log_tgs_alt_tgt(krb5_context context, krb5_principal p);
/* FAST*/
enum krb5_fast_kdc_flags {
@@ -374,7 +359,8 @@ krb5_error_code kdc_fast_handle_reply_key(struct kdc_request_state *state,
krb5_error_code kdc_preauth_get_cookie(struct kdc_request_state *state,
krb5_pa_data **cookie);
krb5_error_code
-kdc_handle_protected_negotiation( krb5_data *req_pkt, krb5_kdc_req *request,
+kdc_handle_protected_negotiation( krb5_context context,
+ krb5_data *req_pkt, krb5_kdc_req *request,
const krb5_keyblock *reply_key,
krb5_pa_data ***out_enc_padata);
krb5_error_code
diff --git a/src/kdc/main.c b/src/kdc/main.c
index 5b5673c..0e9e87e 100644
--- a/src/kdc/main.c
+++ b/src/kdc/main.c
@@ -68,10 +68,15 @@ static volatile int sighup_received = 0;
#define KRB5_KDC_MAX_REALMS 32
-static krb5_context kdc_err_context;
static const char *kdc_progname;
/*
+ * Static server_handle for this file. Other code will get access to
+ * it through the application handle that net-server.c uses.
+ */
+static struct server_handle shandle;
+
+/*
* We use krb5_klog_init to set up a com_err callback to log error
* messages. The callback also pulls the error message out of the
* context we pass to krb5_klog_init; however, we use realm-specific
@@ -87,7 +92,7 @@ kdc_err(krb5_context call_context, errcode_t code, const char *fmt, ...)
va_list ap;
if (call_context)
- krb5_copy_error_message(kdc_err_context, call_context);
+ krb5_copy_error_message(shandle.kdc_err_context, call_context);
va_start(ap, fmt);
com_err_va(kdc_progname, code, fmt, ap);
va_end(ap);
@@ -97,9 +102,12 @@ kdc_err(krb5_context call_context, errcode_t code, const char *fmt, ...)
* Find the realm entry for a given realm.
*/
kdc_realm_t *
-find_realm_data(char *rname, krb5_ui_4 rsize)
+find_realm_data(struct server_handle *handle, char *rname, krb5_ui_4 rsize)
{
int i;
+ kdc_realm_t **kdc_realmlist = handle->kdc_realmlist;
+ int kdc_numrealms = handle->kdc_numrealms;
+
for (i=0; i<kdc_numrealms; i++) {
if ((rsize == strlen(kdc_realmlist[i]->realm_name)) &&
!strncmp(rname, kdc_realmlist[i]->realm_name, rsize))
@@ -108,23 +116,24 @@ find_realm_data(char *rname, krb5_ui_4 rsize)
return((kdc_realm_t *) NULL);
}
-krb5_error_code
-setup_server_realm(krb5_principal sprinc)
+kdc_realm_t *
+setup_server_realm(struct server_handle *handle, krb5_principal sprinc)
{
krb5_error_code kret;
kdc_realm_t *newrealm;
+ kdc_realm_t **kdc_realmlist = handle->kdc_realmlist;
+ int kdc_numrealms = handle->kdc_numrealms;
kret = 0;
if (kdc_numrealms > 1) {
- if (!(newrealm = find_realm_data(sprinc->realm.data,
+ if (!(newrealm = find_realm_data(handle, sprinc->realm.data,
(krb5_ui_4) sprinc->realm.length)))
- kret = ENOENT;
+ return NULL;
else
- kdc_active_realm = newrealm;
+ return newrealm;
}
else
- kdc_active_realm = kdc_realmlist[0];
- return(kret);
+ return kdc_realmlist[0];
}
static void
@@ -558,7 +567,7 @@ create_workers(verto_ctx *ctx, int num)
_("Unable to reinitialize main loop"));
return ENOMEM;
}
- retval = loop_setup_signals(ctx, NULL, reset_for_hangup);
+ retval = loop_setup_signals(ctx, &shandle, reset_for_hangup);
if (retval) {
krb5_klog_syslog(LOG_ERR, _("Unable to initialize signal "
"handlers in pid %d"), pid);
@@ -626,7 +635,8 @@ create_workers(verto_ctx *ctx, int num)
static krb5_error_code
setup_sam(void)
{
- return krb5_c_make_random_key(kdc_context, ENCTYPE_DES_CBC_MD5, &psr_key);
+ krb5_context ctx = shandle.kdc_err_context;
+ return krb5_c_make_random_key(ctx, ENCTYPE_DES_CBC_MD5, &psr_key);
}
static void
@@ -736,7 +746,7 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
break;
case 'r': /* realm name for db */
- if (!find_realm_data(optarg, (krb5_ui_4) strlen(optarg))) {
+ if (!find_realm_data(&shandle, optarg, (krb5_ui_4) strlen(optarg))) {
if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) {
if ((retval = init_realm(rdatap, optarg, mkey_name,
menctype, default_udp_ports,
@@ -748,8 +758,8 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
argv[0], optarg);
exit(1);
}
- kdc_realmlist[kdc_numrealms] = rdatap;
- kdc_numrealms++;
+ shandle.kdc_realmlist[shandle.kdc_numrealms] = rdatap;
+ shandle.kdc_numrealms++;
free(db_args), db_args=NULL, db_args_size = 0;
}
else
@@ -844,7 +854,7 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
/*
* Check to see if we processed any realms.
*/
- if (kdc_numrealms == 0) {
+ if (shandle.kdc_numrealms == 0) {
/* no realm specified, use default realm */
if ((retval = krb5_get_default_realm(kcontext, &lrealm))) {
com_err(argv[0], retval,
@@ -863,14 +873,12 @@ initialize_realms(krb5_context kcontext, int argc, char **argv)
"file for details\n"), argv[0], lrealm);
exit(1);
}
- kdc_realmlist[0] = rdatap;
- kdc_numrealms++;
+ shandle.kdc_realmlist[0] = rdatap;
+ shandle.kdc_numrealms++;
}
krb5_free_default_realm(kcontext, lrealm);
}
- /* Ensure that this is set for our first request. */
- kdc_active_realm = kdc_realmlist[0];
if (default_udp_ports)
free(default_udp_ports);
if (default_tcp_ports)
@@ -907,11 +915,11 @@ finish_realms()
{
int i;
- for (i = 0; i < kdc_numrealms; i++) {
- finish_realm(kdc_realmlist[i]);
- kdc_realmlist[i] = 0;
+ for (i = 0; i < shandle.kdc_numrealms; i++) {
+ finish_realm(shandle.kdc_realmlist[i]);
+ shandle.kdc_realmlist[i] = 0;
}
- kdc_numrealms = 0;
+ shandle.kdc_numrealms = 0;
}
/*
@@ -952,12 +960,13 @@ int main(int argc, char **argv)
if (strrchr(argv[0], '/'))
argv[0] = strrchr(argv[0], '/')+1;
- if (!(kdc_realmlist = (kdc_realm_t **) malloc(sizeof(kdc_realm_t *) *
- KRB5_KDC_MAX_REALMS))) {
+ shandle.kdc_realmlist = malloc(sizeof(kdc_realm_t *) *
+ KRB5_KDC_MAX_REALMS);
+ if (shandle.kdc_realmlist == NULL) {
fprintf(stderr, _("%s: cannot get memory for realm list\n"), argv[0]);
exit(1);
}
- memset(kdc_realmlist, 0,
+ memset(shandle.kdc_realmlist, 0,
(size_t) (sizeof(kdc_realm_t *) * KRB5_KDC_MAX_REALMS));
/*
@@ -972,7 +981,7 @@ int main(int argc, char **argv)
exit(1);
}
krb5_klog_init(kcontext, "kdc", argv[0], 1);
- kdc_err_context = kcontext;
+ shandle.kdc_err_context = kcontext;
kdc_progname = argv[0];
/* N.B.: After this point, com_err sends output to the KDC log
file, and not to stderr. We use the kdc_err wrapper around
@@ -1002,7 +1011,7 @@ int main(int argc, char **argv)
return 1;
}
- load_preauth_plugins(kcontext);
+ load_preauth_plugins(&shandle, kcontext);
load_authdata_plugins(kcontext);
retval = setup_sam();
@@ -1013,8 +1022,8 @@ int main(int argc, char **argv)
}
/* Handle each realm's ports */
- for (i=0; i<kdc_numrealms; i++) {
- char *cp = kdc_realmlist[i]->realm_ports;
+ for (i=0; i< shandle.kdc_numrealms; i++) {
+ char *cp = shandle.kdc_realmlist[i]->realm_ports;
int port;
while (cp && *cp) {
if (*cp == ',' || isspace((int) *cp)) {
@@ -1029,7 +1038,7 @@ int main(int argc, char **argv)
goto net_init_error;
}
- cp = kdc_realmlist[i]->realm_tcp_ports;
+ cp = shandle.kdc_realmlist[i]->realm_tcp_ports;
while (cp && *cp) {
if (*cp == ',' || isspace((int) *cp)) {
cp++;
@@ -1051,20 +1060,20 @@ int main(int argc, char **argv)
* platform has pktinfo support and doesn't need reconfigs.
*/
if (workers == 0) {
- retval = loop_setup_routing_socket(ctx, NULL, kdc_progname);
+ retval = loop_setup_routing_socket(ctx, &shandle, kdc_progname);
if (retval) {
kdc_err(kcontext, retval, _("while initializing routing socket"));
finish_realms();
return 1;
}
- retval = loop_setup_signals(ctx, NULL, reset_for_hangup);
+ retval = loop_setup_signals(ctx, &shandle, reset_for_hangup);
if (retval) {
kdc_err(kcontext, retval, _("while initializing signal handlers"));
finish_realms();
return 1;
}
}
- if ((retval = loop_setup_network(ctx, NULL, kdc_progname))) {
+ if ((retval = loop_setup_network(ctx, &shandle, kdc_progname))) {
net_init_error:
kdc_err(kcontext, retval, _("while initializing network"));
finish_realms();
@@ -1102,10 +1111,10 @@ int main(int argc, char **argv)
krb5_klog_syslog(LOG_INFO, _("shutting down"));
unload_preauth_plugins(kcontext);
unload_authdata_plugins(kcontext);
- krb5_klog_close(kdc_context);
+ krb5_klog_close(kcontext);
finish_realms();
- if (kdc_realmlist)
- free(kdc_realmlist);
+ if (shandle.kdc_realmlist)
+ free(shandle.kdc_realmlist);
#ifndef NOCACHE
kdc_free_lookaside(kcontext);
#endif
diff --git a/src/kdc/realm_data.h b/src/kdc/realm_data.h
new file mode 100644
index 0000000..0387c28
--- /dev/null
+++ b/src/kdc/realm_data.h
@@ -0,0 +1,107 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* kdc/realm_data.h */
+/*
+ * Copyright (C) 2012 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER 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.
+ */
+
+#ifndef REALM_DATA_H
+#define REALM_DATA_H
+
+typedef struct __kdc_realm_data {
+ /*
+ * General Kerberos per-realm data.
+ */
+ char * realm_name; /* Realm name */
+/* XXX the real context should go away once the db_context is done.
+ * The db_context is then associated with the realm keytab using
+ * krb5_ktkdb_resolv(). There should be nothing in the context which
+ * cannot span multiple realms -- proven */
+ krb5_context realm_context; /* Context to be used for realm */
+ krb5_keytab realm_keytab; /* keytab to be used for this realm */
+ char * realm_profile; /* Profile file for this realm */
+ char * realm_host_based_services; /* do referral processing for these services
+ * If '*' - allow all referrals */
+ char * realm_no_host_referral; /* no referral for these services.
+ * If '*' - disallow all referrals and
+ * ignore realm_host_based_services */
+ /*
+ * Database per-realm data.
+ */
+ char * realm_stash; /* Stash file name for realm */
+ char * realm_mpname; /* Master principal name for realm */
+ krb5_principal realm_mprinc; /* Master principal for realm */
+ /*
+ * Note realm_mkey is mkey read from stash or keyboard and may not be the
+ * latest.
+ */
+ krb5_keyblock realm_mkey; /* Master key for this realm */
+ /*
+ * TGS per-realm data.
+ */
+ krb5_principal realm_tgsprinc; /* TGS principal for this realm */
+ /*
+ * Other per-realm data.
+ */
+ char *realm_ports; /* Per-realm KDC UDP port */
+ char *realm_tcp_ports; /* Per-realm KDC TCP port */
+ /*
+ * Per-realm parameters.
+ */
+ krb5_deltat realm_maxlife; /* Maximum ticket life for realm */
+ krb5_deltat realm_maxrlife; /* Maximum renewable life for realm */
+ krb5_boolean realm_reject_bad_transit; /* Accept unverifiable transited_realm ? */
+ krb5_boolean realm_restrict_anon; /* Anon to local TGT only */
+ krb5_boolean realm_assume_des_crc_sess; /* Assume princs support des-cbc-crc for session keys */
+} kdc_realm_t;
+
+struct server_handle {
+ kdc_realm_t **kdc_realmlist;
+ int kdc_numrealms;
+ krb5_context kdc_err_context;
+};
+
+kdc_realm_t *find_realm_data(struct server_handle *, char *, krb5_ui_4);
+kdc_realm_t *setup_server_realm(struct server_handle *, krb5_principal);
+
+/*
+ * These macros used to refer to a global pointer to the active realm state
+ * structure for a request. They now refer to a local variable that must be
+ * properly declared in each function that uses these macros.
+ */
+#define kdc_context kdc_active_realm->realm_context
+#define max_life_for_realm kdc_active_realm->realm_maxlife
+#define max_renewable_life_for_realm kdc_active_realm->realm_maxrlife
+#define master_keyblock kdc_active_realm->realm_mkey
+#define master_princ kdc_active_realm->realm_mprinc
+#define tgs_server kdc_active_realm->realm_tgsprinc
+#define reject_bad_transit kdc_active_realm->realm_reject_bad_transit
+#define restrict_anon kdc_active_realm->realm_restrict_anon
+#define assume_des_crc_sess kdc_active_realm->realm_assume_des_crc_sess
+
+#endif /* REALM_DATA_H */
diff --git a/src/kdc/replay.c b/src/kdc/replay.c
index 2df9cc6..3eee6e8 100644
--- a/src/kdc/replay.c
+++ b/src/kdc/replay.c
@@ -157,13 +157,14 @@ kdc_remove_lookaside(krb5_context kcontext, krb5_data *req_packet)
e = find_entry(req_packet);
if (e != NULL)
- discard_entry(kdc_context, e);
+ discard_entry(kcontext, e);
}
/* Return true and fill in reply_packet_out if req_packet is in the lookaside
* cache; otherwise return false. Also discard old entries in the cache. */
krb5_boolean
-kdc_check_lookaside(krb5_data *req_packet, krb5_data **reply_packet_out)
+kdc_check_lookaside(krb5_context kcontext, krb5_data *req_packet,
+ krb5_data **reply_packet_out)
{
struct entry *e;
@@ -176,21 +177,22 @@ kdc_check_lookaside(krb5_data *req_packet, krb5_data **reply_packet_out)
e->num_hits++;
hits++;
- return (krb5_copy_data(kdc_context, &e->reply_packet,
+ return (krb5_copy_data(kcontext, &e->reply_packet,
reply_packet_out) == 0);
}
/* Insert a request and reply into the lookaside cache. Assumes it's not
* already there, and can fail silently on memory exhaustion. */
void
-kdc_insert_lookaside(krb5_data *req_packet, krb5_data *reply_packet)
+kdc_insert_lookaside(krb5_context kcontext, krb5_data *req_packet,
+ krb5_data *reply_packet)
{
struct entry *e, *next;
krb5_timestamp timenow;
krb5_ui_4 hash = murmurhash3(req_packet);
size_t esize = entry_size(req_packet, reply_packet);
- if (krb5_timeofday(kdc_context, &timenow))
+ if (krb5_timeofday(kcontext, &timenow))
return;
/* Purge stale entries and limit the total size of the entries. */
@@ -198,7 +200,7 @@ kdc_insert_lookaside(krb5_data *req_packet, krb5_data *reply_packet)
if (!STALE(e, timenow) && total_size + esize <= LOOKASIDE_MAX_SIZE)
break;
max_hits_per_entry = max(max_hits_per_entry, e->num_hits);
- discard_entry(kdc_context, e);
+ discard_entry(kcontext, e);
}
/* Create a new entry for this request and reply. */
@@ -206,14 +208,14 @@ kdc_insert_lookaside(krb5_data *req_packet, krb5_data *reply_packet)
if (e == NULL)
return;
e->timein = timenow;
- if (krb5int_copy_data_contents(kdc_context, req_packet, &e->req_packet)) {
+ if (krb5int_copy_data_contents(kcontext, req_packet, &e->req_packet)) {
free(e);
return;
}
if (reply_packet != NULL &&
- krb5int_copy_data_contents(kdc_context, reply_packet,
+ krb5int_copy_data_contents(kcontext, reply_packet,
&e->reply_packet)) {
- krb5_free_data_contents(kdc_context, &e->req_packet);
+ krb5_free_data_contents(kcontext, &e->req_packet);
free(e);
return;
}
diff --git a/src/kdc/reqstate.h b/src/kdc/reqstate.h
new file mode 100644
index 0000000..58dd616
--- /dev/null
+++ b/src/kdc/reqstate.h
@@ -0,0 +1,53 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* kdc/reqstate.h */
+/*
+ * Copyright (C) 2012 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER 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.
+ */
+
+#ifndef REQSTATE_H
+#define REQSTATE_H
+
+#include "realm_data.h"
+
+/* Request state */
+
+struct kdc_request_state {
+ krb5_keyblock *armor_key;
+ krb5_keyblock *strengthen_key;
+ krb5_pa_data *cookie;
+ krb5_int32 fast_options;
+ krb5_int32 fast_internal_flags;
+ kdc_realm_t *realm_data;
+};
+
+krb5_error_code kdc_make_rstate(kdc_realm_t *active_realm,
+ struct kdc_request_state **out);
+void kdc_free_rstate(struct kdc_request_state *s);
+
+#endif /* REQSTATE_H */
diff --git a/src/kdc/rtest.c b/src/kdc/rtest.c
index 446001c..6852284 100644
--- a/src/kdc/rtest.c
+++ b/src/kdc/rtest.c
@@ -109,4 +109,9 @@ main(int argc, char **argv)
}
void krb5_klog_syslog(void) {}
-kdc_realm_t *find_realm_data (char *rname, krb5_ui_4 rsize) { return 0; }
+kdc_realm_t *
+find_realm_data(struct server_handle *handle,
+ char *rname, krb5_ui_4 rsize)
+{
+ return 0;
+}
diff --git a/src/lib/apputils/net-server.c b/src/lib/apputils/net-server.c
index 1f8a8f9..3aa6fde 100644
--- a/src/lib/apputils/net-server.c
+++ b/src/lib/apputils/net-server.c
@@ -277,7 +277,7 @@ do_break(verto_ctx *ctx, verto_ev *ev)
struct sighup_context {
void *handle;
- void (*reset)();
+ void (*reset)(void *);
};
static void
@@ -288,7 +288,7 @@ do_reset(verto_ctx *ctx, verto_ev *ev)
krb5_klog_syslog(LOG_DEBUG, _("Got signal to reset"));
krb5_klog_reopen(get_context(sc->handle));
if (sc->reset)
- sc->reset();
+ sc->reset(sc->handle);
}
static void
More information about the cvs-krb5
mailing list