68
98
krb5_transited enc_tkt_transited;
69
99
int newtransited = 0;
70
100
krb5_error_code retval = 0;
101
krb5_keyblock encrypting_key;
72
103
krb5_boolean more;
73
104
krb5_timestamp kdc_time, authtime=0;
74
105
krb5_keyblock session_key;
75
106
krb5_timestamp until, rtime;
76
krb5_keyblock encrypting_key;
107
krb5_keyblock *reply_key = NULL;
108
krb5_keyblock *mkey_ptr;
77
109
krb5_key_data *server_key;
78
char *cname = 0, *sname = 0, *tmp = 0;
79
const char *fromstring = 0;
110
char *cname = 0, *sname = 0, *altcname = 0;
80
111
krb5_last_req_entry *nolrarray[2], nolrentry;
81
/* krb5_address *noaddrarray[1]; */
82
112
krb5_enctype useenctype;
83
int errcode, errcode2;
113
int errcode, errcode2;
85
115
int firstpass = 1;
86
const char *status = 0;
88
char rep_etypestr[128];
89
char fromstringbuf[70];
116
const char *status = 0;
117
krb5_enc_tkt_part *header_enc_tkt = NULL; /* ticket granting or evidence ticket */
118
krb5_db_entry client, krbtgt;
119
int c_nprincs = 0, k_nprincs = 0;
120
krb5_pa_for_user *for_user = NULL; /* protocol transition request */
121
krb5_authdata **kdc_issued_auth_data = NULL; /* auth data issued by KDC */
122
unsigned int c_flags = 0, s_flags = 0; /* client/server KDB flags */
123
char *s4u_name = NULL;
124
krb5_boolean is_referral, db_ref_done = FALSE;
125
const char *emsg = NULL;
126
krb5_data *tgs_1 =NULL, *server_1 = NULL;
127
krb5_principal krbtgt_princ;
128
krb5_kvno ticket_kvno = 0;
129
struct kdc_request_state *state = NULL;
130
krb5_pa_data *pa_tgs_req; /*points into request*/
91
session_key.contents = 0;
133
session_key.contents = NULL;
93
135
retval = decode_krb5_tgs_req(pkt, &request);
97
ktypes2str(ktypestr, sizeof(ktypestr),
98
request->nktypes, request->ktype);
100
140
* setup_server_realm() sets up the global realm-specific data pointer.
102
if ((retval = setup_server_realm(request->server)))
105
fromstring = inet_ntop(ADDRTYPE2FAMILY(from->address->addrtype),
106
from->address->contents,
107
fromstringbuf, sizeof(fromstringbuf));
109
fromstring = "<unknown>";
111
if ((errcode = krb5_unparse_name(kdc_context, request->server, &sname))) {
112
status = "UNPARSING SERVER";
142
if ((retval = setup_server_realm(request->server))) {
143
krb5_free_kdc_req(kdc_context, request);
117
/* errcode = kdc_process_tgs_req(request, from, pkt, &req_authdat); */
118
errcode = kdc_process_tgs_req(request, from, pkt, &header_ticket, &subkey);
146
errcode = kdc_process_tgs_req(request, from, pkt, &header_ticket,
147
&krbtgt, &k_nprincs, &subkey, &pa_tgs_req);
120
148
if (header_ticket && header_ticket->enc_part2 &&
121
(errcode2 = krb5_unparse_name(kdc_context,
122
header_ticket->enc_part2->client,
124
status = "UNPARSING CLIENT";
149
(errcode2 = krb5_unparse_name(kdc_context,
150
header_ticket->enc_part2->client,
152
status = "UNPARSING CLIENT";
128
156
limit_string(cname);
131
status = "PROCESS_TGS";
159
status = "PROCESS_TGS";
135
163
if (!header_ticket) {
136
errcode = KRB5_NO_TKT_SUPPLIED; /* XXX? */
137
status="UNEXPECTED NULL in header_ticket";
164
errcode = KRB5_NO_TKT_SUPPLIED; /* XXX? */
165
status="UNEXPECTED NULL in header_ticket";
168
errcode = kdc_make_rstate(&state);
170
status = "making state";
173
scratch.length = pa_tgs_req->length;
174
scratch.data = (char *) pa_tgs_req->contents;
175
errcode = kdc_find_fast(&request, &scratch, subkey, header_ticket->enc_part2->session, state);
177
status = "kdc_find_fast";
183
* Pointer to the encrypted part of the header ticket, which may be
184
* replaced to point to the encrypted part of the evidence ticket
185
* if constrained delegation is used. This simplifies the number of
186
* special cases for constrained delegation.
188
header_enc_tkt = header_ticket->enc_part2;
142
191
* We've already dealt with the AP_REQ authentication, so we can
144
193
* decrypted with the session key.
147
authtime = header_ticket->enc_part2->times.authtime;
149
196
/* XXX make sure server here has the proper realm...taken from AP_REQ
199
if (isflagset(request->kdc_options, KDC_OPT_CANONICALIZE)) {
200
setflag(c_flags, KRB5_KDB_FLAG_CANONICALIZE);
201
setflag(s_flags, KRB5_KDB_FLAG_CANONICALIZE);
153
if ((errcode = krb5_db_get_principal(kdc_context, request->server, &server,
155
status = "LOOKING_UP_SERVER";
207
if ((errcode = krb5_unparse_name(kdc_context, request->server, &sname))) {
208
status = "UNPARSING SERVER";
213
errcode = krb5_db_get_principal_ext(kdc_context,
220
status = "LOOKING_UP_SERVER";
161
status = "NON_UNIQUE_PRINCIPAL";
162
errcode = KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE;
226
status = "NON_UNIQUE_PRINCIPAL";
227
errcode = KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE;
164
229
} else if (nprincs != 1) {
166
* might be a request for a TGT for some other realm; we
167
* should do our best to find such a TGS in this db
169
if (firstpass && krb5_is_tgs_principal(request->server) == TRUE) {
170
if (krb5_princ_size(kdc_context, request->server) == 2) {
171
krb5_data *server_1 =
172
krb5_princ_component(kdc_context, request->server, 1);
174
krb5_princ_component(kdc_context, tgs_server, 1);
176
if (!tgs_1 || server_1->length != tgs_1->length ||
177
memcmp(server_1->data, tgs_1->data, tgs_1->length)) {
178
krb5_db_free_principal(kdc_context, &server, nprincs);
179
find_alternate_tgs(request, &server, &more, &nprincs);
185
krb5_db_free_principal(kdc_context, &server, nprincs);
186
status = "UNKNOWN_SERVER";
187
errcode = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
231
* might be a request for a TGT for some other realm; we
232
* should do our best to find such a TGS in this db
236
if ( krb5_is_tgs_principal(request->server) == TRUE) { /* Principal is a name of krb ticket service */
237
if (krb5_princ_size(kdc_context, request->server) == 2) {
239
server_1 = krb5_princ_component(kdc_context, request->server, 1);
240
tgs_1 = krb5_princ_component(kdc_context, tgs_server, 1);
242
if (!tgs_1 || !data_eq(*server_1, *tgs_1)) {
243
krb5_db_free_principal(kdc_context, &server, nprincs);
244
find_alternate_tgs(request, &server, &more, &nprincs);
249
krb5_db_free_principal(kdc_context, &server, nprincs);
250
status = "UNKNOWN_SERVER";
251
errcode = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
254
} else if ( db_ref_done == FALSE) {
255
retval = prep_reprocess_req(request, &krbtgt_princ);
257
krb5_free_principal(kdc_context, request->server);
258
retval = krb5_copy_principal(kdc_context, krbtgt_princ, &(request->server));
269
krb5_db_free_principal(kdc_context, &server, nprincs);
270
status = "UNKNOWN_SERVER";
271
errcode = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
191
275
if ((errcode = krb5_timeofday(kdc_context, &kdc_time))) {
192
status = "TIME_OF_DAY";
276
status = "TIME_OF_DAY";
196
280
if ((retval = validate_tgs_request(request, server, header_ticket,
197
kdc_time, &status))) {
199
status = "UNKNOWN_REASON";
200
errcode = retval + ERROR_TABLE_BASE_krb5;
281
kdc_time, &status))) {
283
status = "UNKNOWN_REASON";
284
errcode = retval + ERROR_TABLE_BASE_krb5;
288
if (!is_local_principal(header_enc_tkt->client))
289
setflag(c_flags, KRB5_KDB_FLAG_CROSS_REALM);
291
is_referral = krb5_is_tgs_principal(server.princ) &&
292
!krb5_principal_compare(kdc_context, tgs_server, server.princ);
294
/* Check for protocol transition */
295
errcode = kdc_process_s4u2self_req(kdc_context, request, header_enc_tkt->client,
296
&server, header_enc_tkt->session, kdc_time,
297
&for_user, &client, &c_nprincs, &status);
300
if (for_user != NULL)
301
setflag(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION);
205
304
* We pick the session keytype here....
213
312
* to anything else.
216
if (isflagset(request->kdc_options, KDC_OPT_ENC_TKT_IN_SKEY)) {
217
krb5_keyblock * st_sealing_key;
218
krb5_kvno st_srv_kvno;
222
* Get the key for the second ticket, and decrypt it.
224
if ((errcode = kdc_get_server_key(request->second_ticket[st_idx],
227
status = "2ND_TKT_SERVER";
230
errcode = krb5_decrypt_tkt_part(kdc_context, st_sealing_key,
231
request->second_ticket[st_idx]);
232
krb5_free_keyblock(kdc_context, st_sealing_key);
234
status = "2ND_TKT_DECRYPT";
238
etype = request->second_ticket[st_idx]->enc_part2->session->enctype;
239
if (!krb5_c_valid_enctype(etype)) {
240
status = "BAD_ETYPE_IN_2ND_TKT";
241
errcode = KRB5KDC_ERR_ETYPE_NOSUPP;
245
for (i = 0; i < request->nktypes; i++) {
246
if (request->ktype[i] == etype) {
315
if (isflagset(request->kdc_options, KDC_OPT_ENC_TKT_IN_SKEY |
316
KDC_OPT_CNAME_IN_ADDL_TKT)) {
317
krb5_keyblock * st_sealing_key;
318
krb5_kvno st_srv_kvno;
320
krb5_db_entry st_client;
324
* Get the key for the second ticket, and decrypt it.
326
if ((errcode = kdc_get_server_key(request->second_ticket[st_idx],
328
TRUE, /* match_enctype */
333
status = "2ND_TKT_SERVER";
336
errcode = krb5_decrypt_tkt_part(kdc_context, st_sealing_key,
337
request->second_ticket[st_idx]);
338
krb5_free_keyblock(kdc_context, st_sealing_key);
340
status = "2ND_TKT_DECRYPT";
341
krb5_db_free_principal(kdc_context, &st_client, st_nprincs);
345
etype = request->second_ticket[st_idx]->enc_part2->session->enctype;
346
if (!krb5_c_valid_enctype(etype)) {
347
status = "BAD_ETYPE_IN_2ND_TKT";
348
errcode = KRB5KDC_ERR_ETYPE_NOSUPP;
349
krb5_db_free_principal(kdc_context, &st_client, st_nprincs);
353
for (i = 0; i < request->nktypes; i++) {
354
if (request->ktype[i] == etype) {
360
if (isflagset(request->kdc_options, KDC_OPT_CNAME_IN_ADDL_TKT)) {
361
/* Do constrained delegation protocol and authorization checks */
362
errcode = kdc_process_s4u2proxy_req(kdc_context,
364
request->second_ticket[st_idx]->enc_part2,
366
header_ticket->enc_part2->client,
372
setflag(c_flags, KRB5_KDB_FLAG_CONSTRAINED_DELEGATION);
374
assert(krb5_is_tgs_principal(header_ticket->server));
376
/* From now on, use evidence ticket as header ticket */
377
header_enc_tkt = request->second_ticket[st_idx]->enc_part2;
379
assert(c_nprincs == 0); /* assured by kdc_process_s4u2self_req() */
382
c_nprincs = st_nprincs;
384
/* "client" is not used for user2user */
385
krb5_db_free_principal(kdc_context, &st_client, st_nprincs);
254
390
* Select the keytype for the ticket session key.
256
392
if ((useenctype == 0) &&
257
(useenctype = select_session_keytype(kdc_context, &server,
259
request->ktype)) == 0) {
260
/* unsupported ktype */
261
status = "BAD_ENCRYPTION_TYPE";
262
errcode = KRB5KDC_ERR_ETYPE_NOSUPP;
393
(useenctype = select_session_keytype(kdc_context, &server,
395
request->ktype)) == 0) {
396
/* unsupported ktype */
397
status = "BAD_ENCRYPTION_TYPE";
398
errcode = KRB5KDC_ERR_ETYPE_NOSUPP;
266
402
errcode = krb5_c_make_random_key(kdc_context, useenctype, &session_key);
269
/* random key failed */
270
status = "RANDOM_KEY_FAILED";
405
/* random key failed */
406
status = "RANDOM_KEY_FAILED";
274
ticket_reply.server = request->server; /* XXX careful for realm... */
410
authtime = header_enc_tkt->times.authtime;
413
ticket_reply.server = server.princ;
415
ticket_reply.server = request->server; /* XXX careful for realm... */
276
417
enc_tkt_reply.flags = 0;
277
418
enc_tkt_reply.times.starttime = 0;
420
if (isflagset(server.attributes, KRB5_KDB_OK_AS_DELEGATE) &&
422
/* Ensure that we are not returning a referral */
423
setflag(enc_tkt_reply.flags, TKT_FLG_OK_AS_DELEGATE);
280
427
* Fix header_ticket's starttime; if it's zero, fill in the
281
428
* authtime's value.
283
if (!(header_ticket->enc_part2->times.starttime))
284
header_ticket->enc_part2->times.starttime =
285
header_ticket->enc_part2->times.authtime;
430
if (!(header_enc_tkt->times.starttime))
431
header_enc_tkt->times.starttime = header_enc_tkt->times.authtime;
287
433
/* don't use new addresses unless forwarded, see below */
289
enc_tkt_reply.caddrs = header_ticket->enc_part2->caddrs;
435
enc_tkt_reply.caddrs = header_enc_tkt->caddrs;
290
436
/* noaddrarray[0] = 0; */
291
reply_encpart.caddrs = 0; /* optional...don't put it in */
437
reply_encpart.caddrs = 0;/* optional...don't put it in */
438
reply_encpart.enc_padata = NULL;
293
440
/* It should be noted that local policy may affect the */
294
441
/* processing of any of these flags. For example, some */
295
442
/* realms may refuse to issue renewable tickets */
297
444
if (isflagset(request->kdc_options, KDC_OPT_FORWARDABLE))
298
setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
445
setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
446
if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION)) {
447
if (!krb5_is_tgs_principal(server.princ) &&
448
is_local_principal(server.princ)) {
449
if (isflagset(server.attributes, KRB5_KDB_OK_TO_AUTH_AS_DELEGATE))
450
setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
452
clear(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
454
if (isflagset(client.attributes, KRB5_KDB_DISALLOW_FORWARDABLE))
455
clear(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
300
457
if (isflagset(request->kdc_options, KDC_OPT_FORWARDED)) {
301
setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDED);
303
/* include new addresses in ticket & reply */
305
enc_tkt_reply.caddrs = request->addresses;
306
reply_encpart.caddrs = request->addresses;
308
if (isflagset(header_ticket->enc_part2->flags, TKT_FLG_FORWARDED))
309
setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDED);
458
setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDED);
460
/* include new addresses in ticket & reply */
462
enc_tkt_reply.caddrs = request->addresses;
463
reply_encpart.caddrs = request->addresses;
465
if (isflagset(header_enc_tkt->flags, TKT_FLG_FORWARDED))
466
setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDED);
311
468
if (isflagset(request->kdc_options, KDC_OPT_PROXIABLE))
312
setflag(enc_tkt_reply.flags, TKT_FLG_PROXIABLE);
469
setflag(enc_tkt_reply.flags, TKT_FLG_PROXIABLE);
314
471
if (isflagset(request->kdc_options, KDC_OPT_PROXY)) {
315
setflag(enc_tkt_reply.flags, TKT_FLG_PROXY);
317
/* include new addresses in ticket & reply */
319
enc_tkt_reply.caddrs = request->addresses;
320
reply_encpart.caddrs = request->addresses;
472
setflag(enc_tkt_reply.flags, TKT_FLG_PROXY);
474
/* include new addresses in ticket & reply */
476
enc_tkt_reply.caddrs = request->addresses;
477
reply_encpart.caddrs = request->addresses;
323
480
if (isflagset(request->kdc_options, KDC_OPT_ALLOW_POSTDATE))
324
setflag(enc_tkt_reply.flags, TKT_FLG_MAY_POSTDATE);
481
setflag(enc_tkt_reply.flags, TKT_FLG_MAY_POSTDATE);
326
483
if (isflagset(request->kdc_options, KDC_OPT_POSTDATED)) {
327
setflag(enc_tkt_reply.flags, TKT_FLG_POSTDATED);
328
setflag(enc_tkt_reply.flags, TKT_FLG_INVALID);
329
enc_tkt_reply.times.starttime = request->from;
484
setflag(enc_tkt_reply.flags, TKT_FLG_POSTDATED);
485
setflag(enc_tkt_reply.flags, TKT_FLG_INVALID);
486
enc_tkt_reply.times.starttime = request->from;
331
enc_tkt_reply.times.starttime = kdc_time;
488
enc_tkt_reply.times.starttime = kdc_time;
333
490
if (isflagset(request->kdc_options, KDC_OPT_VALIDATE)) {
334
/* BEWARE of allocation hanging off of ticket & enc_part2, it belongs
336
ticket_reply = *(header_ticket);
337
enc_tkt_reply = *(header_ticket->enc_part2);
338
clear(enc_tkt_reply.flags, TKT_FLG_INVALID);
491
assert(isflagset(c_flags, KRB5_KDB_FLAGS_S4U) == 0);
492
/* BEWARE of allocation hanging off of ticket & enc_part2, it belongs
494
ticket_reply = *(header_ticket);
495
enc_tkt_reply = *(header_ticket->enc_part2);
496
clear(enc_tkt_reply.flags, TKT_FLG_INVALID);
341
499
if (isflagset(request->kdc_options, KDC_OPT_RENEW)) {
342
krb5_deltat old_life;
344
/* BEWARE of allocation hanging off of ticket & enc_part2, it belongs
346
ticket_reply = *(header_ticket);
347
enc_tkt_reply = *(header_ticket->enc_part2);
349
old_life = enc_tkt_reply.times.endtime - enc_tkt_reply.times.starttime;
351
enc_tkt_reply.times.starttime = kdc_time;
352
enc_tkt_reply.times.endtime =
353
min(header_ticket->enc_part2->times.renew_till,
354
kdc_time + old_life);
500
krb5_deltat old_life;
502
assert(isflagset(c_flags, KRB5_KDB_FLAGS_S4U) == 0);
503
/* BEWARE of allocation hanging off of ticket & enc_part2, it belongs
505
ticket_reply = *(header_ticket);
506
enc_tkt_reply = *(header_ticket->enc_part2);
508
old_life = enc_tkt_reply.times.endtime - enc_tkt_reply.times.starttime;
510
enc_tkt_reply.times.starttime = kdc_time;
511
enc_tkt_reply.times.endtime =
512
min(header_ticket->enc_part2->times.renew_till,
513
kdc_time + old_life);
356
/* not a renew request */
357
enc_tkt_reply.times.starttime = kdc_time;
358
until = (request->till == 0) ? kdc_infinity : request->till;
359
enc_tkt_reply.times.endtime =
360
min(until, min(enc_tkt_reply.times.starttime + server.max_life,
361
min(enc_tkt_reply.times.starttime + max_life_for_realm,
362
header_ticket->enc_part2->times.endtime)));
363
if (isflagset(request->kdc_options, KDC_OPT_RENEWABLE_OK) &&
364
(enc_tkt_reply.times.endtime < request->till) &&
365
isflagset(header_ticket->enc_part2->flags,
366
TKT_FLG_RENEWABLE)) {
367
setflag(request->kdc_options, KDC_OPT_RENEWABLE);
370
header_ticket->enc_part2->times.renew_till);
515
/* not a renew request */
516
enc_tkt_reply.times.starttime = kdc_time;
517
until = (request->till == 0) ? kdc_infinity : request->till;
518
enc_tkt_reply.times.endtime =
519
min(until, min(enc_tkt_reply.times.starttime + server.max_life,
520
min(enc_tkt_reply.times.starttime + max_life_for_realm,
521
header_enc_tkt->times.endtime)));
522
if (isflagset(request->kdc_options, KDC_OPT_RENEWABLE_OK) &&
523
(enc_tkt_reply.times.endtime < request->till) &&
524
isflagset(header_enc_tkt->flags, TKT_FLG_RENEWABLE)) {
525
setflag(request->kdc_options, KDC_OPT_RENEWABLE);
527
min(request->till, header_enc_tkt->times.renew_till);
373
530
rtime = (request->rtime == 0) ? kdc_infinity : request->rtime;
375
532
if (isflagset(request->kdc_options, KDC_OPT_RENEWABLE)) {
376
/* already checked above in policy check to reject request for a
377
renewable ticket using a non-renewable ticket */
378
setflag(enc_tkt_reply.flags, TKT_FLG_RENEWABLE);
379
enc_tkt_reply.times.renew_till =
381
min(header_ticket->enc_part2->times.renew_till,
382
enc_tkt_reply.times.starttime +
383
min(server.max_renewable_life,
384
max_renewable_life_for_realm)));
533
/* already checked above in policy check to reject request for a
534
renewable ticket using a non-renewable ticket */
535
setflag(enc_tkt_reply.flags, TKT_FLG_RENEWABLE);
536
enc_tkt_reply.times.renew_till =
538
min(header_enc_tkt->times.renew_till,
539
enc_tkt_reply.times.starttime +
540
min(server.max_renewable_life,
541
max_renewable_life_for_realm)));
386
enc_tkt_reply.times.renew_till = 0;
543
enc_tkt_reply.times.renew_till = 0;
390
547
* Set authtime to be the same as header_ticket's
392
enc_tkt_reply.times.authtime = header_ticket->enc_part2->times.authtime;
549
enc_tkt_reply.times.authtime = header_enc_tkt->times.authtime;
395
552
* Propagate the preauthentication flags through to the returned ticket.
397
if (isflagset(header_ticket->enc_part2->flags, TKT_FLG_PRE_AUTH))
398
setflag(enc_tkt_reply.flags, TKT_FLG_PRE_AUTH);
554
if (isflagset(header_enc_tkt->flags, TKT_FLG_PRE_AUTH))
555
setflag(enc_tkt_reply.flags, TKT_FLG_PRE_AUTH);
400
if (isflagset(header_ticket->enc_part2->flags, TKT_FLG_HW_AUTH))
401
setflag(enc_tkt_reply.flags, TKT_FLG_HW_AUTH);
557
if (isflagset(header_enc_tkt->flags, TKT_FLG_HW_AUTH))
558
setflag(enc_tkt_reply.flags, TKT_FLG_HW_AUTH);
403
560
/* starttime is optional, and treated as authtime if not present.
404
561
so we can nuke it if it matches */
405
562
if (enc_tkt_reply.times.starttime == enc_tkt_reply.times.authtime)
406
enc_tkt_reply.times.starttime = 0;
408
/* assemble any authorization data */
409
if (request->authorization_data.ciphertext.data) {
412
scratch.length = request->authorization_data.ciphertext.length;
414
malloc(request->authorization_data.ciphertext.length))) {
415
status = "AUTH_NOMEM";
420
if ((errcode = krb5_c_decrypt(kdc_context,
421
header_ticket->enc_part2->session,
422
KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY,
423
0, &request->authorization_data,
425
status = "AUTH_ENCRYPT_FAIL";
430
/* scratch now has the authorization data, so we decode it */
431
errcode = decode_krb5_authdata(&scratch, &(request->unenc_authdata));
434
status = "AUTH_DECODE";
439
concat_authorization_data(request->unenc_authdata,
440
header_ticket->enc_part2->authorization_data,
441
&enc_tkt_reply.authorization_data))) {
442
status = "CONCAT_AUTH";
446
enc_tkt_reply.authorization_data =
447
header_ticket->enc_part2->authorization_data;
563
enc_tkt_reply.times.starttime = 0;
565
if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION)) {
566
errcode = krb5_unparse_name(kdc_context, for_user->user, &s4u_name);
567
} else if (isflagset(c_flags, KRB5_KDB_FLAG_CONSTRAINED_DELEGATION)) {
568
errcode = krb5_unparse_name(kdc_context, header_enc_tkt->client, &s4u_name);
573
status = "UNPARSING S4U CLIENT";
577
if (isflagset(request->kdc_options, KDC_OPT_ENC_TKT_IN_SKEY)) {
578
krb5_enc_tkt_part *t2enc = request->second_ticket[st_idx]->enc_part2;
579
encrypting_key = *(t2enc->session);
582
* Find the server key
584
if ((errcode = krb5_dbe_find_enctype(kdc_context, &server,
585
-1, /* ignore keytype */
586
-1, /* Ignore salttype */
587
0,/* Get highest kvno */
589
status = "FINDING_SERVER_KEY";
593
if ((errcode = krb5_dbe_find_mkey(kdc_context, master_keylist, &server,
595
krb5_keylist_node *tmp_mkey_list;
596
/* try refreshing master key list */
597
/* XXX it would nice if we had the mkvno here for optimization */
598
if (krb5_db_fetch_mkey_list(kdc_context, master_princ,
599
&master_keyblock, 0, &tmp_mkey_list) == 0) {
600
krb5_dbe_free_key_list(kdc_context, master_keylist);
601
master_keylist = tmp_mkey_list;
602
if ((errcode = krb5_dbe_find_mkey(kdc_context, master_keylist,
603
&server, &mkey_ptr))) {
604
status = "FINDING_MASTER_KEY";
608
status = "FINDING_MASTER_KEY";
613
/* convert server.key into a real key (it may be encrypted
614
* in the database) */
615
if ((errcode = krb5_dbekd_decrypt_key_data(kdc_context,
617
server_key, &encrypting_key,
619
status = "DECRYPT_SERVER_KEY";
624
if (isflagset(c_flags, KRB5_KDB_FLAG_CONSTRAINED_DELEGATION)) {
626
* Don't allow authorization data to be disabled if constrained
627
* delegation is requested. We don't want to deny the server
628
* the ability to validate that delegation was used.
630
clear(server.attributes, KRB5_KDB_NO_AUTH_DATA_REQUIRED);
632
if (isflagset(server.attributes, KRB5_KDB_NO_AUTH_DATA_REQUIRED) == 0) {
634
* If we are not doing protocol transition/constrained delegation
635
* and there was no authorization data included, try to lookup
636
* the client principal as it may be mapped to a local account.
638
* Always validate authorization data for constrained delegation
639
* because we must validate the KDC signatures.
641
if (!isflagset(c_flags, KRB5_KDB_FLAGS_S4U) &&
642
header_enc_tkt->authorization_data == NULL) {
644
/* Generate authorization data so we can include it in ticket */
645
setflag(c_flags, KRB5_KDB_FLAG_INCLUDE_PAC);
646
/* Map principals from foreign (possibly non-AD) realms */
647
setflag(c_flags, KRB5_KDB_FLAG_MAP_PRINCIPALS);
649
assert(c_nprincs == 0); /* should not have been looked up already */
652
errcode = krb5_db_get_principal_ext(kdc_context,
653
header_enc_tkt->client,
659
* We can ignore errors because the principal may be a
660
* valid cross-realm principal for which we have no local
661
* mapping. But we do want to check that at most one entry
664
if (errcode == 0 && (more || c_nprincs > 1)) {
665
errcode = KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE;
667
} else if (errcode) {
673
enc_tkt_reply.authorization_data = NULL;
675
if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION) &&
676
is_local_principal(header_enc_tkt->client))
677
enc_tkt_reply.client = for_user->user;
679
enc_tkt_reply.client = header_enc_tkt->client;
681
errcode = handle_authdata(kdc_context,
683
(c_nprincs != 0) ? &client : NULL,
685
(k_nprincs != 0) ? &krbtgt : NULL,
686
subkey != NULL ? subkey :
687
header_ticket->enc_part2->session,
688
&encrypting_key, /* U2U or server key */
691
for_user ? for_user->user : NULL,
695
krb5_klog_syslog(LOG_INFO, "TGS_REQ : handle_authdata (%d)", errcode);
696
status = "HANDLE_AUTHDATA";
700
if (is_referral && isflagset(s_flags, KRB5_KDB_FLAG_CANONICALIZE)) {
701
errcode = return_svr_referral_data(kdc_context,
702
&server, &reply_encpart);
704
status = "KDC_RETURN_ENC_PADATA";
449
709
enc_tkt_reply.session = &session_key;
450
enc_tkt_reply.client = header_ticket->enc_part2->client;
451
710
enc_tkt_reply.transited.tr_type = KRB5_DOMAIN_X500_COMPRESS;
452
711
enc_tkt_reply.transited.tr_contents = empty_string; /* equivalent of "" */
462
721
/* realm compare is like strcmp, but knows how to deal with these args */
463
722
if (realm_compare(header_ticket->server, tgs_server) ||
464
realm_compare(header_ticket->server, enc_tkt_reply.client)) {
465
/* tgt issued by local realm or issued by realm of client */
466
enc_tkt_reply.transited = header_ticket->enc_part2->transited;
723
realm_compare(header_ticket->server, enc_tkt_reply.client)) {
724
/* tgt issued by local realm or issued by realm of client */
725
enc_tkt_reply.transited = header_enc_tkt->transited;
468
/* tgt issued by some other realm and not the realm of the client */
469
/* assemble new transited field into allocated storage */
470
if (header_ticket->enc_part2->transited.tr_type !=
471
KRB5_DOMAIN_X500_COMPRESS) {
472
status = "BAD_TRTYPE";
473
errcode = KRB5KDC_ERR_TRTYPE_NOSUPP;
476
enc_tkt_transited.tr_type = KRB5_DOMAIN_X500_COMPRESS;
477
enc_tkt_transited.magic = 0;
478
enc_tkt_transited.tr_contents.magic = 0;
479
enc_tkt_transited.tr_contents.data = 0;
480
enc_tkt_transited.tr_contents.length = 0;
481
enc_tkt_reply.transited = enc_tkt_transited;
483
add_to_transited(&header_ticket->enc_part2->transited.tr_contents,
484
&enc_tkt_reply.transited.tr_contents,
485
header_ticket->server,
486
enc_tkt_reply.client,
488
status = "ADD_TR_FAIL";
727
/* tgt issued by some other realm and not the realm of the client */
728
/* assemble new transited field into allocated storage */
729
if (header_enc_tkt->transited.tr_type !=
730
KRB5_DOMAIN_X500_COMPRESS) {
731
status = "BAD_TRTYPE";
732
errcode = KRB5KDC_ERR_TRTYPE_NOSUPP;
735
enc_tkt_transited.tr_type = KRB5_DOMAIN_X500_COMPRESS;
736
enc_tkt_transited.magic = 0;
737
enc_tkt_transited.tr_contents.magic = 0;
738
enc_tkt_transited.tr_contents.data = 0;
739
enc_tkt_transited.tr_contents.length = 0;
740
enc_tkt_reply.transited = enc_tkt_transited;
742
add_to_transited(&header_enc_tkt->transited.tr_contents,
743
&enc_tkt_reply.transited.tr_contents,
744
header_ticket->server,
745
enc_tkt_reply.client,
747
status = "ADD_TR_FAIL";
752
if (isflagset(c_flags, KRB5_KDB_FLAG_CROSS_REALM)) {
753
errcode = validate_transit_path(kdc_context, header_enc_tkt->client,
755
(k_nprincs != 0) ? &krbtgt : NULL);
757
status = "NON_TRANSITIVE";
493
761
if (!isflagset (request->kdc_options, KDC_OPT_DISABLE_TRANSITED_CHECK)) {
497
errcode = krb5_check_transited_list (kdc_context,
498
&enc_tkt_reply.transited.tr_contents,
499
krb5_princ_realm (kdc_context, header_ticket->enc_part2->client),
500
krb5_princ_realm (kdc_context, request->server));
501
tlen = enc_tkt_reply.transited.tr_contents.length;
502
tdots = tlen > 125 ? "..." : "";
503
tlen = tlen > 125 ? 125 : tlen;
506
setflag (enc_tkt_reply.flags, TKT_FLG_TRANSIT_POLICY_CHECKED);
507
} else if (errcode == KRB5KRB_AP_ERR_ILL_CR_TKT)
508
krb5_klog_syslog (LOG_INFO,
509
"bad realm transit path from '%s' to '%s' "
511
cname ? cname : "<unknown client>",
512
sname ? sname : "<unknown server>",
514
enc_tkt_reply.transited.tr_contents.data,
517
const char *emsg = krb5_get_error_message(kdc_context, errcode);
518
krb5_klog_syslog (LOG_ERR,
519
"unexpected error checking transit from "
520
"'%s' to '%s' via '%.*s%s': %s",
521
cname ? cname : "<unknown client>",
522
sname ? sname : "<unknown server>",
524
enc_tkt_reply.transited.tr_contents.data,
526
krb5_free_error_message(kdc_context, emsg);
765
errcode = kdc_check_transited_list (kdc_context,
766
&enc_tkt_reply.transited.tr_contents,
767
krb5_princ_realm (kdc_context, header_enc_tkt->client),
768
krb5_princ_realm (kdc_context, request->server));
769
tlen = enc_tkt_reply.transited.tr_contents.length;
770
tdots = tlen > 125 ? "..." : "";
771
tlen = tlen > 125 ? 125 : tlen;
774
setflag (enc_tkt_reply.flags, TKT_FLG_TRANSIT_POLICY_CHECKED);
775
} else if (errcode == KRB5KRB_AP_ERR_ILL_CR_TKT)
776
krb5_klog_syslog (LOG_INFO,
777
"bad realm transit path from '%s' to '%s' "
779
cname ? cname : "<unknown client>",
780
sname ? sname : "<unknown server>",
782
enc_tkt_reply.transited.tr_contents.data,
785
emsg = krb5_get_error_message(kdc_context, errcode);
786
krb5_klog_syslog (LOG_ERR,
787
"unexpected error checking transit from "
788
"'%s' to '%s' via '%.*s%s': %s",
789
cname ? cname : "<unknown client>",
790
sname ? sname : "<unknown server>",
792
enc_tkt_reply.transited.tr_contents.data,
794
krb5_free_error_message(kdc_context, emsg);
529
krb5_klog_syslog (LOG_INFO, "not checking transit path");
798
krb5_klog_syslog (LOG_INFO, "not checking transit path");
530
799
if (reject_bad_transit
531
&& !isflagset (enc_tkt_reply.flags, TKT_FLG_TRANSIT_POLICY_CHECKED)) {
532
errcode = KRB5KDC_ERR_POLICY;
533
status = "BAD_TRANSIT";
800
&& !isflagset (enc_tkt_reply.flags, TKT_FLG_TRANSIT_POLICY_CHECKED)) {
801
errcode = KRB5KDC_ERR_POLICY;
802
status = "BAD_TRANSIT";
537
806
ticket_reply.enc_part2 = &enc_tkt_reply;
640
880
reply.enc_part.enctype = subkey ? subkey->enctype :
641
header_ticket->enc_part2->session->enctype;
642
errcode = krb5_encode_kdc_rep(kdc_context, KRB5_TGS_REP, &reply_encpart,
645
header_ticket->enc_part2->session,
648
status = "ENCODE_KDC_REP";
881
header_ticket->enc_part2->session->enctype;
882
errcode = kdc_fast_response_handle_padata(state, request, &reply,
883
subkey?subkey->enctype:header_ticket->enc_part2->session->enctype);
885
status = "Preparing FAST padata";
888
errcode =kdc_fast_handle_reply_key(state, subkey?subkey:header_ticket->enc_part2->session, &reply_key);
890
status = "generating reply key";
893
errcode = krb5_encode_kdc_rep(kdc_context, KRB5_TGS_REP, &reply_encpart,
898
status = "ENCODE_KDC_REP";
653
903
memset(ticket_reply.enc_part.ciphertext.data, 0,
654
ticket_reply.enc_part.ciphertext.length);
904
ticket_reply.enc_part.ciphertext.length);
655
905
free(ticket_reply.enc_part.ciphertext.data);
656
906
/* these parts are left on as a courtesy from krb5_encode_kdc_rep so we
657
907
can use them in raw form if needed. But, we don't... */
658
908
memset(reply.enc_part.ciphertext.data, 0,
659
reply.enc_part.ciphertext.length);
909
reply.enc_part.ciphertext.length);
660
910
free(reply.enc_part.ciphertext.data);
664
const char * emsg = NULL;
666
rep_etypes2str(rep_etypestr, sizeof(rep_etypestr), &reply);
668
emsg = krb5_get_error_message (kdc_context, errcode);
669
krb5_klog_syslog(LOG_INFO,
670
"TGS_REQ (%s) %s: %s: authtime %d, "
671
"%s%s %s for %s%s%s",
673
fromstring, status, authtime,
674
!errcode ? rep_etypestr : "",
676
cname ? cname : "<unknown client>",
677
sname ? sname : "<unknown server>",
679
errcode ? emsg : "");
681
krb5_free_error_message (kdc_context, emsg);
913
assert(status != NULL);
915
krb5_free_keyblock(kdc_context, reply_key);
917
emsg = krb5_get_error_message (kdc_context, errcode);
918
log_tgs_req(from, request, &reply, cname, sname, altcname, authtime,
919
c_flags, s4u_name, status, errcode, emsg);
921
krb5_free_error_message (kdc_context, emsg);
687
status = krb5_get_error_message (kdc_context, errcode);
690
errcode -= ERROR_TABLE_BASE_krb5;
691
if (errcode < 0 || errcode > 128)
692
errcode = KRB_ERR_GENERIC;
694
retval = prepare_error_tgs(request, header_ticket, errcode,
695
fromstring, response, status);
697
krb5_free_error_message (kdc_context, status);
928
status = krb5_get_error_message (kdc_context, errcode);
931
errcode -= ERROR_TABLE_BASE_krb5;
932
if (errcode < 0 || errcode > 128)
933
errcode = KRB_ERR_GENERIC;
935
retval = prepare_error_tgs(state, request, header_ticket, errcode,
936
nprincs ? server.princ : NULL,
939
krb5_free_error_message (kdc_context, status);
703
krb5_free_ticket(kdc_context, header_ticket);
705
krb5_free_kdc_req(kdc_context, request);
711
krb5_db_free_principal(kdc_context, &server, 1);
712
if (session_key.contents)
713
krb5_free_keyblock_contents(kdc_context, &session_key);
944
if (header_ticket != NULL)
945
krb5_free_ticket(kdc_context, header_ticket);
947
krb5_free_kdc_req(kdc_context, request);
949
kdc_free_rstate(state);
955
krb5_db_free_principal(kdc_context, &server, 1);
956
if (session_key.contents != NULL)
957
krb5_free_keyblock_contents(kdc_context, &session_key);
714
958
if (newtransited)
715
free(enc_tkt_reply.transited.tr_contents.data);
959
free(enc_tkt_reply.transited.tr_contents.data);
961
krb5_db_free_principal(kdc_context, &krbtgt, k_nprincs);
963
krb5_db_free_principal(kdc_context, &client, c_nprincs);
964
if (for_user != NULL)
965
krb5_free_pa_for_user(kdc_context, for_user);
966
if (kdc_issued_auth_data != NULL)
967
krb5_free_authdata(kdc_context, kdc_issued_auth_data);
968
if (s4u_name != NULL)
971
krb5_free_keyblock(kdc_context, subkey);
720
976
static krb5_error_code
721
prepare_error_tgs (krb5_kdc_req *request, krb5_ticket *ticket, int error,
722
const char *ident, krb5_data **response, const char *status)
977
prepare_error_tgs (struct kdc_request_state *state,
978
krb5_kdc_req *request, krb5_ticket *ticket, int error,
979
krb5_principal canon_server,
980
krb5_data **response, const char *status)
724
982
krb5_error errpkt;
725
krb5_error_code retval;
983
krb5_error_code retval = 0;
726
984
krb5_data *scratch;
728
986
errpkt.ctime = request->nonce;
729
987
errpkt.cusec = 0;
731
989
if ((retval = krb5_us_timeofday(kdc_context, &errpkt.stime,
734
992
errpkt.error = error;
735
993
errpkt.server = request->server;
736
994
if (ticket && ticket->enc_part2)
737
errpkt.client = ticket->enc_part2->client;
995
errpkt.client = ticket->enc_part2->client;
997
errpkt.client = NULL;
740
998
errpkt.text.length = strlen(status) + 1;
741
if (!(errpkt.text.data = malloc(errpkt.text.length)))
743
(void) strcpy(errpkt.text.data, status);
999
if (!(errpkt.text.data = strdup(status)))
745
1002
if (!(scratch = (krb5_data *)malloc(sizeof(*scratch)))) {
1003
free(errpkt.text.data);
1006
errpkt.e_data.length = 0;
1007
errpkt.e_data.data = NULL;
1009
retval = kdc_fast_handle_error(kdc_context, state, request, NULL, &errpkt);
746
1012
free(errpkt.text.data);
749
errpkt.e_data.length = 0;
750
errpkt.e_data.data = 0;
752
1015
retval = krb5_mk_error(kdc_context, &errpkt, scratch);
753
1016
free(errpkt.text.data);
1020
*response = scratch;