This commit was manufactured by cvs2svn to create tag
[heimdal.git] / kdc / kerberos5.c
blob67d7ab5b7bdf1c7921fa231c8db54f90e09131c7
1 /*
2 * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #include "kdc_locl.h"
36 RCSID("$Id$");
38 #define MAX_TIME ((time_t)((1U << 31) - 1))
40 static void
41 fix_time(time_t **t)
43 if(*t == NULL){
44 ALLOC(*t);
45 **t = MAX_TIME;
47 if(**t == 0) **t = MAX_TIME; /* fix for old clients */
50 static int
51 realloc_method_data(METHOD_DATA *md)
53 PA_DATA *pa;
54 pa = realloc(md->val, (md->len + 1) * sizeof(*md->val));
55 if(pa == NULL)
56 return ENOMEM;
57 md->val = pa;
58 md->len++;
59 return 0;
62 static void
63 set_salt_padata (METHOD_DATA *md, Salt *salt)
65 if (salt) {
66 realloc_method_data(md);
67 md->val[md->len - 1].padata_type = salt->type;
68 copy_octet_string(&salt->salt,
69 &md->val[md->len - 1].padata_value);
73 static PA_DATA*
74 find_padata(KDC_REQ *req, int *start, int type)
76 while(*start < req->padata->len){
77 (*start)++;
78 if(req->padata->val[*start - 1].padata_type == type)
79 return &req->padata->val[*start - 1];
81 return NULL;
85 * return the first appropriate key of `princ' in `ret_key'. Look for
86 * all the etypes in (`etypes', `len'), stopping as soon as we find
87 * one, but preferring one that has default salt
90 static krb5_error_code
91 find_etype(hdb_entry *princ, krb5_enctype *etypes, unsigned len,
92 Key **ret_key, krb5_enctype *ret_etype)
94 int i;
95 krb5_error_code ret = KRB5KDC_ERR_ETYPE_NOSUPP;
97 for(i = 0; ret != 0 && i < len ; i++) {
98 Key *key = NULL;
100 if (krb5_enctype_valid(context, etypes[i]) != 0)
101 continue;
103 while (hdb_next_enctype2key(context, princ, etypes[i], &key) == 0) {
104 if (key->key.keyvalue.length == 0) {
105 ret = KRB5KDC_ERR_NULL_KEY;
106 continue;
108 *ret_key = key;
109 *ret_etype = etypes[i];
110 ret = 0;
111 if (key->salt == NULL)
112 return ret;
115 return ret;
118 static krb5_error_code
119 find_keys(hdb_entry *client,
120 hdb_entry *server,
121 Key **ckey,
122 krb5_enctype *cetype,
123 Key **skey,
124 krb5_enctype *setype,
125 krb5_enctype *etypes,
126 unsigned num_etypes)
128 char unparse_name[] = "krb5_unparse_name failed";
129 krb5_error_code ret;
130 char *name;
132 if(client){
133 /* find client key */
134 ret = find_etype(client, etypes, num_etypes, ckey, cetype);
135 if (ret) {
136 if (krb5_unparse_name(context, client->principal, &name) != 0)
137 name = unparse_name;
138 kdc_log(0, "Client (%s) has no support for etypes", name);
139 if (name != unparse_name)
140 free(name);
141 return ret;
145 if(server){
146 /* find server key */
147 ret = find_etype(server, etypes, num_etypes, skey, setype);
148 if (ret) {
149 if (krb5_unparse_name(context, server->principal, &name) != 0)
150 name = unparse_name;
151 kdc_log(0, "Server (%s) has no support for etypes", name);
152 if (name != unparse_name)
153 free(name);
154 return ret;
157 return 0;
160 static krb5_error_code
161 make_anonymous_principalname (PrincipalName *pn)
163 pn->name_type = KRB5_NT_PRINCIPAL;
164 pn->name_string.len = 1;
165 pn->name_string.val = malloc(sizeof(*pn->name_string.val));
166 if (pn->name_string.val == NULL)
167 return ENOMEM;
168 pn->name_string.val[0] = strdup("anonymous");
169 if (pn->name_string.val[0] == NULL) {
170 free(pn->name_string.val);
171 pn->name_string.val = NULL;
172 return ENOMEM;
174 return 0;
177 static krb5_error_code
178 encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek,
179 krb5_enctype etype,
180 int skvno, EncryptionKey *skey,
181 int ckvno, EncryptionKey *ckey,
182 const char **e_text,
183 krb5_data *reply)
185 unsigned char *buf;
186 size_t buf_size;
187 size_t len;
188 krb5_error_code ret;
189 krb5_crypto crypto;
191 ASN1_MALLOC_ENCODE(EncTicketPart, buf, buf_size, et, &len, ret);
192 if(ret) {
193 kdc_log(0, "Failed to encode ticket: %s",
194 krb5_get_err_text(context, ret));
195 return ret;
197 if(buf_size != len) {
198 free(buf);
199 kdc_log(0, "Internal error in ASN.1 encoder");
200 *e_text = "KDC internal error";
201 return KRB5KRB_ERR_GENERIC;
204 ret = krb5_crypto_init(context, skey, etype, &crypto);
205 if (ret) {
206 free(buf);
207 kdc_log(0, "krb5_crypto_init failed: %s",
208 krb5_get_err_text(context, ret));
209 return ret;
212 ret = krb5_encrypt_EncryptedData(context,
213 crypto,
214 KRB5_KU_TICKET,
215 buf,
216 len,
217 skvno,
218 &rep->ticket.enc_part);
219 free(buf);
220 krb5_crypto_destroy(context, crypto);
221 if(ret) {
222 kdc_log(0, "Failed to encrypt data: %s",
223 krb5_get_err_text(context, ret));
224 return ret;
227 if(rep->msg_type == krb_as_rep && !encode_as_rep_as_tgs_rep)
228 ASN1_MALLOC_ENCODE(EncASRepPart, buf, buf_size, ek, &len, ret);
229 else
230 ASN1_MALLOC_ENCODE(EncTGSRepPart, buf, buf_size, ek, &len, ret);
231 if(ret) {
232 kdc_log(0, "Failed to encode KDC-REP: %s",
233 krb5_get_err_text(context, ret));
234 return ret;
236 if(buf_size != len) {
237 free(buf);
238 kdc_log(0, "Internal error in ASN.1 encoder");
239 *e_text = "KDC internal error";
240 return KRB5KRB_ERR_GENERIC;
242 ret = krb5_crypto_init(context, ckey, 0, &crypto);
243 if (ret) {
244 free(buf);
245 kdc_log(0, "krb5_crypto_init failed: %s",
246 krb5_get_err_text(context, ret));
247 return ret;
249 if(rep->msg_type == krb_as_rep) {
250 krb5_encrypt_EncryptedData(context,
251 crypto,
252 KRB5_KU_AS_REP_ENC_PART,
253 buf,
254 len,
255 ckvno,
256 &rep->enc_part);
257 free(buf);
258 ASN1_MALLOC_ENCODE(AS_REP, buf, buf_size, rep, &len, ret);
259 } else {
260 krb5_encrypt_EncryptedData(context,
261 crypto,
262 KRB5_KU_TGS_REP_ENC_PART_SESSION,
263 buf,
264 len,
265 ckvno,
266 &rep->enc_part);
267 free(buf);
268 ASN1_MALLOC_ENCODE(TGS_REP, buf, buf_size, rep, &len, ret);
270 krb5_crypto_destroy(context, crypto);
271 if(ret) {
272 kdc_log(0, "Failed to encode KDC-REP: %s",
273 krb5_get_err_text(context, ret));
274 return ret;
276 if(buf_size != len) {
277 free(buf);
278 kdc_log(0, "Internal error in ASN.1 encoder");
279 *e_text = "KDC internal error";
280 return KRB5KRB_ERR_GENERIC;
282 reply->data = buf;
283 reply->length = buf_size;
284 return 0;
287 static krb5_error_code
288 make_etype_info_entry(ETYPE_INFO_ENTRY *ent, Key *key)
290 ent->etype = key->key.keytype;
291 if(key->salt){
292 ALLOC(ent->salttype);
293 #if 0
294 if(key->salt->type == hdb_pw_salt)
295 *ent->salttype = 0; /* or 1? or NULL? */
296 else if(key->salt->type == hdb_afs3_salt)
297 *ent->salttype = 2;
298 else {
299 kdc_log(0, "unknown salt-type: %d",
300 key->salt->type);
301 return KRB5KRB_ERR_GENERIC;
303 /* according to `the specs', we can't send a salt if
304 we have AFS3 salted key, but that requires that you
305 *know* what cell you are using (e.g by assuming
306 that the cell is the same as the realm in lower
307 case) */
308 #else
309 *ent->salttype = key->salt->type;
310 #endif
311 krb5_copy_data(context, &key->salt->salt,
312 &ent->salt);
313 } else {
314 /* we return no salt type at all, as that should indicate
315 * the default salt type and make everybody happy. some
316 * systems (like w2k) dislike being told the salt type
317 * here. */
319 ent->salttype = NULL;
320 ent->salt = NULL;
322 return 0;
325 static krb5_error_code
326 get_pa_etype_info(METHOD_DATA *md, hdb_entry *client,
327 ENCTYPE *etypes, unsigned int etypes_len)
329 krb5_error_code ret = 0;
330 int i, j;
331 unsigned int n = 0;
332 ETYPE_INFO pa;
333 unsigned char *buf;
334 size_t len;
337 pa.len = client->keys.len;
338 if(pa.len > UINT_MAX/sizeof(*pa.val))
339 return ERANGE;
340 pa.val = malloc(pa.len * sizeof(*pa.val));
341 if(pa.val == NULL)
342 return ENOMEM;
343 memset(pa.val, 0, pa.len * sizeof(*pa.val));
345 for(j = 0; j < etypes_len; j++) {
346 for (i = 0; i < n; i++)
347 if (pa.val[i].etype == etypes[j])
348 goto skip1;
349 for(i = 0; i < client->keys.len; i++) {
350 if(client->keys.val[i].key.keytype == etypes[j]) {
351 if (krb5_enctype_valid(context, etypes[j]) != 0)
352 continue;
353 if((ret = make_etype_info_entry(&pa.val[n++],
354 &client->keys.val[i])) != 0) {
355 free_ETYPE_INFO(&pa);
356 return ret;
360 skip1:;
362 for(i = 0; i < client->keys.len; i++) {
363 for(j = 0; j < etypes_len; j++) {
364 if(client->keys.val[i].key.keytype == etypes[j])
365 goto skip2;
367 if (krb5_enctype_valid(context, client->keys.val[i].key.keytype) != 0)
368 continue;
369 if((ret = make_etype_info_entry(&pa.val[n++],
370 &client->keys.val[i])) != 0) {
371 free_ETYPE_INFO(&pa);
372 return ret;
374 skip2:;
377 if(n != pa.len) {
378 char *name;
379 ret = krb5_unparse_name(context, client->principal, &name);
380 if (ret)
381 name = "<unparse_name failed>";
382 kdc_log(0, "internal error in get_pa_etype_info(%s): %d != %d",
383 name, n, pa.len);
384 if (ret == 0)
385 free(name);
386 pa.len = n;
389 ASN1_MALLOC_ENCODE(ETYPE_INFO, buf, len, &pa, &len, ret);
390 free_ETYPE_INFO(&pa);
391 if(ret)
392 return ret;
393 ret = realloc_method_data(md);
394 if(ret) {
395 free(buf);
396 return ret;
398 md->val[md->len - 1].padata_type = KRB5_PADATA_ETYPE_INFO;
399 md->val[md->len - 1].padata_value.length = len;
400 md->val[md->len - 1].padata_value.data = buf;
401 return 0;
408 extern int _krb5_AES_string_to_default_iterator;
410 static krb5_error_code
411 make_etype_info2_entry(ETYPE_INFO2_ENTRY *ent, Key *key)
413 ent->etype = key->key.keytype;
414 if(key->salt) {
415 ALLOC(ent->salt);
416 if (ent->salt == NULL)
417 return ENOMEM;
418 *ent->salt = malloc(key->salt->salt.length + 1);
419 if (*ent->salt == NULL) {
420 free(ent->salt);
421 ent->salt = NULL;
422 return ENOMEM;
424 memcpy(*ent->salt, key->salt->salt.data, key->salt->salt.length);
425 (*ent->salt)[key->salt->salt.length] = '\0';
426 } else
427 ent->salt = NULL;
429 ent->s2kparams = NULL;
431 switch (key->key.keytype) {
432 case KEYTYPE_AES128:
433 case KEYTYPE_AES256:
434 ALLOC(ent->s2kparams);
435 if (ent->s2kparams == NULL)
436 return ENOMEM;
437 ent->s2kparams->length = 4;
438 ent->s2kparams->data = malloc(ent->s2kparams->length);
439 if (ent->s2kparams->data == NULL) {
440 free(ent->s2kparams);
441 ent->s2kparams = NULL;
442 return ENOMEM;
444 _krb5_put_int(ent->s2kparams->data,
445 _krb5_AES_string_to_default_iterator,
446 ent->s2kparams->length);
447 break;
448 default:
449 break;
451 return 0;
455 * Return 1 if the client have only older enctypes, this is for
456 * determining if the server should send ETYPE_INFO2 or not.
459 static int
460 only_older_enctype_p(const KDC_REQ *req)
462 int i;
464 for(i = 0; i < req->req_body.etype.len; i++) {
465 switch (req->req_body.etype.val[i]) {
466 case ETYPE_DES_CBC_CRC:
467 case ETYPE_DES_CBC_MD4:
468 case ETYPE_DES_CBC_MD5:
469 case ETYPE_DES3_CBC_SHA1:
470 case ETYPE_ARCFOUR_HMAC_MD5:
471 case ETYPE_ARCFOUR_HMAC_MD5_56:
472 break;
473 default:
474 return 0;
477 return 1;
484 static krb5_error_code
485 get_pa_etype_info2(METHOD_DATA *md, hdb_entry *client,
486 ENCTYPE *etypes, unsigned int etypes_len)
488 krb5_error_code ret = 0;
489 int i, j;
490 unsigned int n = 0;
491 ETYPE_INFO2 pa;
492 unsigned char *buf;
493 size_t len;
495 pa.len = client->keys.len;
496 if(pa.len > UINT_MAX/sizeof(*pa.val))
497 return ERANGE;
498 pa.val = malloc(pa.len * sizeof(*pa.val));
499 if(pa.val == NULL)
500 return ENOMEM;
501 memset(pa.val, 0, pa.len * sizeof(*pa.val));
503 for(j = 0; j < etypes_len; j++) {
504 for (i = 0; i < n; i++)
505 if (pa.val[i].etype == etypes[j])
506 goto skip1;
507 for(i = 0; i < client->keys.len; i++) {
508 if(client->keys.val[i].key.keytype == etypes[j]) {
509 if (krb5_enctype_valid(context, etypes[j]) != 0)
510 continue;
511 if((ret = make_etype_info2_entry(&pa.val[n++],
512 &client->keys.val[i])) != 0) {
513 free_ETYPE_INFO2(&pa);
514 return ret;
518 skip1:;
520 for(i = 0; i < client->keys.len; i++) {
521 for(j = 0; j < etypes_len; j++) {
522 if(client->keys.val[i].key.keytype == etypes[j])
523 goto skip2;
525 if (krb5_enctype_valid(context, client->keys.val[i].key.keytype) != 0)
526 continue;
527 if((ret = make_etype_info2_entry(&pa.val[n++],
528 &client->keys.val[i])) != 0) {
529 free_ETYPE_INFO2(&pa);
530 return ret;
532 skip2:;
535 if(n != pa.len) {
536 char *name;
537 ret = krb5_unparse_name(context, client->principal, &name);
538 if (ret)
539 name = "<unparse_name failed>";
540 kdc_log(0, "internal error in get_pa_etype_info2(%s): %d != %d",
541 name, n, pa.len);
542 if (ret == 0)
543 free(name);
544 pa.len = n;
547 ASN1_MALLOC_ENCODE(ETYPE_INFO2, buf, len, &pa, &len, ret);
548 free_ETYPE_INFO2(&pa);
549 if(ret)
550 return ret;
551 ret = realloc_method_data(md);
552 if(ret) {
553 free(buf);
554 return ret;
556 md->val[md->len - 1].padata_type = KRB5_PADATA_ETYPE_INFO2;
557 md->val[md->len - 1].padata_value.length = len;
558 md->val[md->len - 1].padata_value.data = buf;
559 return 0;
563 * verify the flags on `client' and `server', returning 0
564 * if they are OK and generating an error messages and returning
565 * and error code otherwise.
568 krb5_error_code
569 check_flags(hdb_entry *client, const char *client_name,
570 hdb_entry *server, const char *server_name,
571 krb5_boolean is_as_req)
573 if(client != NULL) {
574 /* check client */
575 if (client->flags.invalid) {
576 kdc_log(0, "Client (%s) has invalid bit set", client_name);
577 return KRB5KDC_ERR_POLICY;
580 if(!client->flags.client){
581 kdc_log(0, "Principal may not act as client -- %s",
582 client_name);
583 return KRB5KDC_ERR_POLICY;
586 if (client->valid_start && *client->valid_start > kdc_time) {
587 kdc_log(0, "Client not yet valid -- %s", client_name);
588 return KRB5KDC_ERR_CLIENT_NOTYET;
591 if (client->valid_end && *client->valid_end < kdc_time) {
592 kdc_log(0, "Client expired -- %s", client_name);
593 return KRB5KDC_ERR_NAME_EXP;
596 if (client->pw_end && *client->pw_end < kdc_time
597 && !server->flags.change_pw) {
598 kdc_log(0, "Client's key has expired -- %s", client_name);
599 return KRB5KDC_ERR_KEY_EXPIRED;
603 /* check server */
605 if (server != NULL) {
606 if (server->flags.invalid) {
607 kdc_log(0, "Server has invalid flag set -- %s", server_name);
608 return KRB5KDC_ERR_POLICY;
611 if(!server->flags.server){
612 kdc_log(0, "Principal may not act as server -- %s",
613 server_name);
614 return KRB5KDC_ERR_POLICY;
617 if(!is_as_req && server->flags.initial) {
618 kdc_log(0, "AS-REQ is required for server -- %s", server_name);
619 return KRB5KDC_ERR_POLICY;
622 if (server->valid_start && *server->valid_start > kdc_time) {
623 kdc_log(0, "Server not yet valid -- %s", server_name);
624 return KRB5KDC_ERR_SERVICE_NOTYET;
627 if (server->valid_end && *server->valid_end < kdc_time) {
628 kdc_log(0, "Server expired -- %s", server_name);
629 return KRB5KDC_ERR_SERVICE_EXP;
632 if (server->pw_end && *server->pw_end < kdc_time) {
633 kdc_log(0, "Server's key has expired -- %s", server_name);
634 return KRB5KDC_ERR_KEY_EXPIRED;
637 return 0;
641 * Return TRUE if `from' is part of `addresses' taking into consideration
642 * the configuration variables that tells us how strict we should be about
643 * these checks
646 static krb5_boolean
647 check_addresses(HostAddresses *addresses, const struct sockaddr *from)
649 krb5_error_code ret;
650 krb5_address addr;
651 krb5_boolean result;
653 if(check_ticket_addresses == 0)
654 return TRUE;
656 if(addresses == NULL)
657 return allow_null_ticket_addresses;
659 ret = krb5_sockaddr2address (context, from, &addr);
660 if(ret)
661 return FALSE;
663 result = krb5_address_search(context, &addr, addresses);
664 krb5_free_address (context, &addr);
665 return result;
668 krb5_error_code
669 as_rep(KDC_REQ *req,
670 krb5_data *reply,
671 const char *from,
672 struct sockaddr *from_addr)
674 KDC_REQ_BODY *b = &req->req_body;
675 AS_REP rep;
676 KDCOptions f = b->kdc_options;
677 hdb_entry *client = NULL, *server = NULL;
678 krb5_enctype cetype, setype;
679 EncTicketPart et;
680 EncKDCRepPart ek;
681 krb5_principal client_princ = NULL, server_princ = NULL;
682 char *client_name = NULL, *server_name = NULL;
683 krb5_error_code ret = 0;
684 const char *e_text = NULL;
685 krb5_crypto crypto;
686 Key *ckey, *skey;
687 EncryptionKey *reply_key;
688 #ifdef PKINIT
689 pk_client_params *pkp = NULL;
690 #endif
692 memset(&rep, 0, sizeof(rep));
694 if(b->sname == NULL){
695 ret = KRB5KRB_ERR_GENERIC;
696 e_text = "No server in request";
697 } else{
698 _krb5_principalname2krb5_principal (&server_princ,
699 *(b->sname), b->realm);
700 ret = krb5_unparse_name(context, server_princ, &server_name);
702 if (ret) {
703 kdc_log(0, "AS-REQ malformed server name from %s", from);
704 goto out;
707 if(b->cname == NULL){
708 ret = KRB5KRB_ERR_GENERIC;
709 e_text = "No client in request";
710 } else {
711 _krb5_principalname2krb5_principal (&client_princ,
712 *(b->cname), b->realm);
713 ret = krb5_unparse_name(context, client_princ, &client_name);
715 if (ret) {
716 kdc_log(0, "AS-REQ malformed client name from %s", from);
717 goto out;
720 kdc_log(0, "AS-REQ %s from %s for %s",
721 client_name, from, server_name);
723 ret = db_fetch(client_princ, &client);
724 if(ret){
725 kdc_log(0, "UNKNOWN -- %s: %s", client_name,
726 krb5_get_err_text(context, ret));
727 ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
728 goto out;
731 ret = db_fetch(server_princ, &server);
732 if(ret){
733 kdc_log(0, "UNKNOWN -- %s: %s", server_name,
734 krb5_get_err_text(context, ret));
735 ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
736 goto out;
739 ret = check_flags(client, client_name, server, server_name, TRUE);
740 if(ret)
741 goto out;
743 memset(&et, 0, sizeof(et));
744 memset(&ek, 0, sizeof(ek));
746 if(req->padata){
747 int i = 0;
748 PA_DATA *pa;
749 int found_pa = 0;
751 #ifdef PKINIT
752 kdc_log(5, "Looking for PKINIT pa-data -- %s", client_name);
754 e_text = "No PKINIT PA found";
756 i = 0;
757 if ((pa = find_padata(req, &i, KRB5_PADATA_PK_AS_REQ)))
759 if (pa == NULL) {
760 i = 0;
761 if((pa = find_padata(req, &i, KRB5_PADATA_PK_AS_REQ_19)))
764 if (pa == NULL) {
765 i = 0;
766 if((pa = find_padata(req, &i, KRB5_PADATA_PK_AS_REQ_WIN)))
769 if (pa) {
770 char *client_cert = NULL;
772 ret = pk_rd_padata(context, req, pa, &pkp);
773 if (ret) {
774 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
775 kdc_log(5, "Failed to decode PKINIT PA-DATA -- %s",
776 client_name);
777 goto ts_enc;
779 if (ret == 0 && pkp == NULL)
780 goto ts_enc;
782 ret = pk_check_client(context,
783 client_princ,
784 client,
785 pkp,
786 &client_cert);
787 if (ret) {
788 e_text = "PKINIT certificate not allowed to "
789 "impersonate principal";
790 pk_free_client_param(context, pkp);
791 pkp = NULL;
792 goto ts_enc;
794 found_pa = 1;
795 et.flags.pre_authent = 1;
796 kdc_log(2, "PKINIT pre-authentication succeeded -- %s using %s",
797 client_name, client_cert);
798 free(client_cert);
799 if (pkp)
800 goto preauth_done;
802 ts_enc:
803 #endif
804 kdc_log(5, "Looking for ENC-TS pa-data -- %s", client_name);
806 i = 0;
807 e_text = "No ENC-TS found";
808 while((pa = find_padata(req, &i, KRB5_PADATA_ENC_TIMESTAMP))){
809 krb5_data ts_data;
810 PA_ENC_TS_ENC p;
811 size_t len;
812 EncryptedData enc_data;
813 Key *pa_key;
815 found_pa = 1;
817 ret = decode_EncryptedData(pa->padata_value.data,
818 pa->padata_value.length,
819 &enc_data,
820 &len);
821 if (ret) {
822 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
823 kdc_log(5, "Failed to decode PA-DATA -- %s",
824 client_name);
825 goto out;
828 ret = hdb_enctype2key(context, client, enc_data.etype, &pa_key);
829 if(ret){
830 char *estr;
831 e_text = "No key matches pa-data";
832 ret = KRB5KDC_ERR_PREAUTH_FAILED;
833 if(krb5_enctype_to_string(context, enc_data.etype, &estr))
834 estr = NULL;
835 if(estr == NULL)
836 kdc_log(5, "No client key matching pa-data (%d) -- %s",
837 enc_data.etype, client_name);
838 else
839 kdc_log(5, "No client key matching pa-data (%s) -- %s",
840 estr, client_name);
841 free(estr);
843 free_EncryptedData(&enc_data);
844 continue;
847 try_next_key:
848 ret = krb5_crypto_init(context, &pa_key->key, 0, &crypto);
849 if (ret) {
850 kdc_log(0, "krb5_crypto_init failed: %s",
851 krb5_get_err_text(context, ret));
852 free_EncryptedData(&enc_data);
853 continue;
856 ret = krb5_decrypt_EncryptedData (context,
857 crypto,
858 KRB5_KU_PA_ENC_TIMESTAMP,
859 &enc_data,
860 &ts_data);
861 krb5_crypto_destroy(context, crypto);
862 if(ret){
863 if(hdb_next_enctype2key(context, client,
864 enc_data.etype, &pa_key) == 0)
865 goto try_next_key;
866 free_EncryptedData(&enc_data);
867 e_text = "Failed to decrypt PA-DATA";
868 kdc_log (5, "Failed to decrypt PA-DATA -- %s",
869 client_name);
870 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
871 continue;
873 free_EncryptedData(&enc_data);
874 ret = decode_PA_ENC_TS_ENC(ts_data.data,
875 ts_data.length,
877 &len);
878 krb5_data_free(&ts_data);
879 if(ret){
880 e_text = "Failed to decode PA-ENC-TS-ENC";
881 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
882 kdc_log (5, "Failed to decode PA-ENC-TS_ENC -- %s",
883 client_name);
884 continue;
886 free_PA_ENC_TS_ENC(&p);
887 if (abs(kdc_time - p.patimestamp) > context->max_skew) {
888 ret = KRB5KDC_ERR_PREAUTH_FAILED;
889 e_text = "Too large time skew";
890 kdc_log(0, "Too large time skew -- %s", client_name);
891 goto out;
893 et.flags.pre_authent = 1;
894 kdc_log(2, "ENC-TS Pre-authentication succeeded -- %s",
895 client_name);
896 break;
898 #ifdef PKINIT
899 preauth_done:
900 #endif
901 if(found_pa == 0 && require_preauth)
902 goto use_pa;
903 /* We come here if we found a pa-enc-timestamp, but if there
904 was some problem with it, other than too large skew */
905 if(found_pa && et.flags.pre_authent == 0){
906 kdc_log(0, "%s -- %s", e_text, client_name);
907 e_text = NULL;
908 goto out;
910 }else if (require_preauth
911 || client->flags.require_preauth
912 || server->flags.require_preauth) {
913 METHOD_DATA method_data;
914 PA_DATA *pa;
915 unsigned char *buf;
916 size_t len;
917 krb5_data foo_data;
919 use_pa:
920 method_data.len = 0;
921 method_data.val = NULL;
923 ret = realloc_method_data(&method_data);
924 pa = &method_data.val[method_data.len-1];
925 pa->padata_type = KRB5_PADATA_ENC_TIMESTAMP;
926 pa->padata_value.length = 0;
927 pa->padata_value.data = NULL;
929 #ifdef PKINIT
930 ret = realloc_method_data(&method_data);
931 pa = &method_data.val[method_data.len-1];
932 pa->padata_type = KRB5_PADATA_PK_AS_REQ;
933 pa->padata_value.length = 0;
934 pa->padata_value.data = NULL;
936 ret = realloc_method_data(&method_data);
937 pa = &method_data.val[method_data.len-1];
938 pa->padata_type = KRB5_PADATA_PK_AS_REQ_19;
939 pa->padata_value.length = 0;
940 pa->padata_value.data = NULL;
941 #endif
943 /* XXX check ret */
944 if (only_older_enctype_p(req))
945 ret = get_pa_etype_info(&method_data, client,
946 b->etype.val, b->etype.len);
947 /* XXX check ret */
948 ret = get_pa_etype_info2(&method_data, client,
949 b->etype.val, b->etype.len);
952 ASN1_MALLOC_ENCODE(METHOD_DATA, buf, len, &method_data, &len, ret);
953 free_METHOD_DATA(&method_data);
954 foo_data.data = buf;
955 foo_data.length = len;
957 ret = KRB5KDC_ERR_PREAUTH_REQUIRED;
958 krb5_mk_error(context,
959 ret,
960 "Need to use PA-ENC-TIMESTAMP/PA-PK-AS-REQ",
961 &foo_data,
962 client_princ,
963 server_princ,
964 NULL,
965 NULL,
966 reply);
967 free(buf);
968 kdc_log(0, "No preauth found, returning PREAUTH-REQUIRED -- %s",
969 client_name);
970 ret = 0;
971 goto out2;
974 ret = find_keys(client, server, &ckey, &cetype, &skey, &setype,
975 b->etype.val, b->etype.len);
976 if(ret) {
977 kdc_log(0, "Server/client has no support for etypes");
978 goto out;
982 char *cet;
983 char *set;
985 ret = krb5_enctype_to_string(context, cetype, &cet);
986 if(ret == 0) {
987 ret = krb5_enctype_to_string(context, setype, &set);
988 if (ret == 0) {
989 kdc_log(5, "Using %s/%s", cet, set);
990 free(set);
992 free(cet);
994 if (ret != 0)
995 kdc_log(5, "Using e-types %d/%d", cetype, setype);
999 char str[128];
1000 unparse_flags(KDCOptions2int(f), asn1_KDCOptions_units(),
1001 str, sizeof(str));
1002 if(*str)
1003 kdc_log(2, "Requested flags: %s", str);
1007 if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey
1008 || (f.request_anonymous && !allow_anonymous)) {
1009 ret = KRB5KDC_ERR_BADOPTION;
1010 kdc_log(0, "Bad KDC options -- %s", client_name);
1011 goto out;
1014 rep.pvno = 5;
1015 rep.msg_type = krb_as_rep;
1016 copy_Realm(&b->realm, &rep.crealm);
1017 if (f.request_anonymous)
1018 make_anonymous_principalname (&rep.cname);
1019 else
1020 copy_PrincipalName(b->cname, &rep.cname);
1021 rep.ticket.tkt_vno = 5;
1022 copy_Realm(&b->realm, &rep.ticket.realm);
1023 copy_PrincipalName(b->sname, &rep.ticket.sname);
1025 et.flags.initial = 1;
1026 if(client->flags.forwardable && server->flags.forwardable)
1027 et.flags.forwardable = f.forwardable;
1028 else if (f.forwardable) {
1029 ret = KRB5KDC_ERR_POLICY;
1030 kdc_log(0, "Ticket may not be forwardable -- %s", client_name);
1031 goto out;
1033 if(client->flags.proxiable && server->flags.proxiable)
1034 et.flags.proxiable = f.proxiable;
1035 else if (f.proxiable) {
1036 ret = KRB5KDC_ERR_POLICY;
1037 kdc_log(0, "Ticket may not be proxiable -- %s", client_name);
1038 goto out;
1040 if(client->flags.postdate && server->flags.postdate)
1041 et.flags.may_postdate = f.allow_postdate;
1042 else if (f.allow_postdate){
1043 ret = KRB5KDC_ERR_POLICY;
1044 kdc_log(0, "Ticket may not be postdatable -- %s", client_name);
1045 goto out;
1048 /* check for valid set of addresses */
1049 if(!check_addresses(b->addresses, from_addr)) {
1050 ret = KRB5KRB_AP_ERR_BADADDR;
1051 kdc_log(0, "Bad address list requested -- %s", client_name);
1052 goto out;
1055 krb5_generate_random_keyblock(context, setype, &et.key);
1056 copy_PrincipalName(&rep.cname, &et.cname);
1057 copy_Realm(&b->realm, &et.crealm);
1060 time_t start;
1061 time_t t;
1063 start = et.authtime = kdc_time;
1065 if(f.postdated && req->req_body.from){
1066 ALLOC(et.starttime);
1067 start = *et.starttime = *req->req_body.from;
1068 et.flags.invalid = 1;
1069 et.flags.postdated = 1; /* XXX ??? */
1071 fix_time(&b->till);
1072 t = *b->till;
1074 /* be careful not overflowing */
1076 if(client->max_life)
1077 t = start + min(t - start, *client->max_life);
1078 if(server->max_life)
1079 t = start + min(t - start, *server->max_life);
1080 #if 0
1081 t = min(t, start + realm->max_life);
1082 #endif
1083 et.endtime = t;
1084 if(f.renewable_ok && et.endtime < *b->till){
1085 f.renewable = 1;
1086 if(b->rtime == NULL){
1087 ALLOC(b->rtime);
1088 *b->rtime = 0;
1090 if(*b->rtime < *b->till)
1091 *b->rtime = *b->till;
1093 if(f.renewable && b->rtime){
1094 t = *b->rtime;
1095 if(t == 0)
1096 t = MAX_TIME;
1097 if(client->max_renew)
1098 t = start + min(t - start, *client->max_renew);
1099 if(server->max_renew)
1100 t = start + min(t - start, *server->max_renew);
1101 #if 0
1102 t = min(t, start + realm->max_renew);
1103 #endif
1104 ALLOC(et.renew_till);
1105 *et.renew_till = t;
1106 et.flags.renewable = 1;
1110 if (f.request_anonymous)
1111 et.flags.anonymous = 1;
1113 if(b->addresses){
1114 ALLOC(et.caddr);
1115 copy_HostAddresses(b->addresses, et.caddr);
1118 et.transited.tr_type = DOMAIN_X500_COMPRESS;
1119 krb5_data_zero(&et.transited.contents);
1121 copy_EncryptionKey(&et.key, &ek.key);
1123 /* The MIT ASN.1 library (obviously) doesn't tell lengths encoded
1124 * as 0 and as 0x80 (meaning indefinite length) apart, and is thus
1125 * incapable of correctly decoding SEQUENCE OF's of zero length.
1127 * To fix this, always send at least one no-op last_req
1129 * If there's a pw_end or valid_end we will use that,
1130 * otherwise just a dummy lr.
1132 ek.last_req.val = malloc(2 * sizeof(*ek.last_req.val));
1133 ek.last_req.len = 0;
1134 if (client->pw_end
1135 && (kdc_warn_pwexpire == 0
1136 || kdc_time + kdc_warn_pwexpire <= *client->pw_end)) {
1137 ek.last_req.val[ek.last_req.len].lr_type = LR_PW_EXPTIME;
1138 ek.last_req.val[ek.last_req.len].lr_value = *client->pw_end;
1139 ++ek.last_req.len;
1141 if (client->valid_end) {
1142 ek.last_req.val[ek.last_req.len].lr_type = LR_ACCT_EXPTIME;
1143 ek.last_req.val[ek.last_req.len].lr_value = *client->valid_end;
1144 ++ek.last_req.len;
1146 if (ek.last_req.len == 0) {
1147 ek.last_req.val[ek.last_req.len].lr_type = LR_NONE;
1148 ek.last_req.val[ek.last_req.len].lr_value = 0;
1149 ++ek.last_req.len;
1151 ek.nonce = b->nonce;
1152 if (client->valid_end || client->pw_end) {
1153 ALLOC(ek.key_expiration);
1154 if (client->valid_end) {
1155 if (client->pw_end)
1156 *ek.key_expiration = min(*client->valid_end, *client->pw_end);
1157 else
1158 *ek.key_expiration = *client->valid_end;
1159 } else
1160 *ek.key_expiration = *client->pw_end;
1161 } else
1162 ek.key_expiration = NULL;
1163 ek.flags = et.flags;
1164 ek.authtime = et.authtime;
1165 if (et.starttime) {
1166 ALLOC(ek.starttime);
1167 *ek.starttime = *et.starttime;
1169 ek.endtime = et.endtime;
1170 if (et.renew_till) {
1171 ALLOC(ek.renew_till);
1172 *ek.renew_till = *et.renew_till;
1174 copy_Realm(&rep.ticket.realm, &ek.srealm);
1175 copy_PrincipalName(&rep.ticket.sname, &ek.sname);
1176 if(et.caddr){
1177 ALLOC(ek.caddr);
1178 copy_HostAddresses(et.caddr, ek.caddr);
1181 ALLOC(rep.padata);
1182 rep.padata->len = 0;
1183 rep.padata->val = NULL;
1185 reply_key = &ckey->key;
1186 #if PKINIT
1187 if (pkp) {
1188 ret = pk_mk_pa_reply(context, pkp, client, req,
1189 &reply_key, rep.padata);
1190 if (ret)
1191 goto out;
1193 #endif
1195 set_salt_padata (rep.padata, ckey->salt);
1197 if (rep.padata->len == 0) {
1198 free(rep.padata);
1199 rep.padata = NULL;
1202 ret = encode_reply(&rep, &et, &ek, setype, server->kvno, &skey->key,
1203 client->kvno, reply_key, &e_text, reply);
1204 free_EncTicketPart(&et);
1205 free_EncKDCRepPart(&ek);
1206 out:
1207 free_AS_REP(&rep);
1208 if(ret){
1209 krb5_mk_error(context,
1210 ret,
1211 e_text,
1212 NULL,
1213 client_princ,
1214 server_princ,
1215 NULL,
1216 NULL,
1217 reply);
1218 ret = 0;
1220 out2:
1221 #ifdef PKINIT
1222 if (pkp)
1223 pk_free_client_param(context, pkp);
1224 #endif
1225 if (client_princ)
1226 krb5_free_principal(context, client_princ);
1227 free(client_name);
1228 if (server_princ)
1229 krb5_free_principal(context, server_princ);
1230 free(server_name);
1231 if(client)
1232 free_ent(client);
1233 if(server)
1234 free_ent(server);
1235 return ret;
1239 static krb5_error_code
1240 check_tgs_flags(KDC_REQ_BODY *b, EncTicketPart *tgt, EncTicketPart *et)
1242 KDCOptions f = b->kdc_options;
1244 if(f.validate){
1245 if(!tgt->flags.invalid || tgt->starttime == NULL){
1246 kdc_log(0, "Bad request to validate ticket");
1247 return KRB5KDC_ERR_BADOPTION;
1249 if(*tgt->starttime > kdc_time){
1250 kdc_log(0, "Early request to validate ticket");
1251 return KRB5KRB_AP_ERR_TKT_NYV;
1253 /* XXX tkt = tgt */
1254 et->flags.invalid = 0;
1255 }else if(tgt->flags.invalid){
1256 kdc_log(0, "Ticket-granting ticket has INVALID flag set");
1257 return KRB5KRB_AP_ERR_TKT_INVALID;
1260 if(f.forwardable){
1261 if(!tgt->flags.forwardable){
1262 kdc_log(0, "Bad request for forwardable ticket");
1263 return KRB5KDC_ERR_BADOPTION;
1265 et->flags.forwardable = 1;
1267 if(f.forwarded){
1268 if(!tgt->flags.forwardable){
1269 kdc_log(0, "Request to forward non-forwardable ticket");
1270 return KRB5KDC_ERR_BADOPTION;
1272 et->flags.forwarded = 1;
1273 et->caddr = b->addresses;
1275 if(tgt->flags.forwarded)
1276 et->flags.forwarded = 1;
1278 if(f.proxiable){
1279 if(!tgt->flags.proxiable){
1280 kdc_log(0, "Bad request for proxiable ticket");
1281 return KRB5KDC_ERR_BADOPTION;
1283 et->flags.proxiable = 1;
1285 if(f.proxy){
1286 if(!tgt->flags.proxiable){
1287 kdc_log(0, "Request to proxy non-proxiable ticket");
1288 return KRB5KDC_ERR_BADOPTION;
1290 et->flags.proxy = 1;
1291 et->caddr = b->addresses;
1293 if(tgt->flags.proxy)
1294 et->flags.proxy = 1;
1296 if(f.allow_postdate){
1297 if(!tgt->flags.may_postdate){
1298 kdc_log(0, "Bad request for post-datable ticket");
1299 return KRB5KDC_ERR_BADOPTION;
1301 et->flags.may_postdate = 1;
1303 if(f.postdated){
1304 if(!tgt->flags.may_postdate){
1305 kdc_log(0, "Bad request for postdated ticket");
1306 return KRB5KDC_ERR_BADOPTION;
1308 if(b->from)
1309 *et->starttime = *b->from;
1310 et->flags.postdated = 1;
1311 et->flags.invalid = 1;
1312 }else if(b->from && *b->from > kdc_time + context->max_skew){
1313 kdc_log(0, "Ticket cannot be postdated");
1314 return KRB5KDC_ERR_CANNOT_POSTDATE;
1317 if(f.renewable){
1318 if(!tgt->flags.renewable){
1319 kdc_log(0, "Bad request for renewable ticket");
1320 return KRB5KDC_ERR_BADOPTION;
1322 et->flags.renewable = 1;
1323 ALLOC(et->renew_till);
1324 fix_time(&b->rtime);
1325 *et->renew_till = *b->rtime;
1327 if(f.renew){
1328 time_t old_life;
1329 if(!tgt->flags.renewable || tgt->renew_till == NULL){
1330 kdc_log(0, "Request to renew non-renewable ticket");
1331 return KRB5KDC_ERR_BADOPTION;
1333 old_life = tgt->endtime;
1334 if(tgt->starttime)
1335 old_life -= *tgt->starttime;
1336 else
1337 old_life -= tgt->authtime;
1338 et->endtime = *et->starttime + old_life;
1339 if (et->renew_till != NULL)
1340 et->endtime = min(*et->renew_till, et->endtime);
1343 /* checks for excess flags */
1344 if(f.request_anonymous && !allow_anonymous){
1345 kdc_log(0, "Request for anonymous ticket");
1346 return KRB5KDC_ERR_BADOPTION;
1348 return 0;
1351 static krb5_error_code
1352 fix_transited_encoding(krb5_boolean check_policy,
1353 TransitedEncoding *tr,
1354 EncTicketPart *et,
1355 const char *client_realm,
1356 const char *server_realm,
1357 const char *tgt_realm)
1359 krb5_error_code ret = 0;
1360 char **realms, **tmp;
1361 int num_realms;
1362 int i;
1364 if(tr->tr_type != DOMAIN_X500_COMPRESS) {
1365 kdc_log(0, "Unknown transited type: %u", tr->tr_type);
1366 return KRB5KDC_ERR_TRTYPE_NOSUPP;
1369 ret = krb5_domain_x500_decode(context,
1370 tr->contents,
1371 &realms,
1372 &num_realms,
1373 client_realm,
1374 server_realm);
1375 if(ret){
1376 krb5_warn(context, ret, "Decoding transited encoding");
1377 return ret;
1379 if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)) {
1380 /* not us, so add the previous realm to transited set */
1381 if (num_realms < 0 || num_realms + 1 > UINT_MAX/sizeof(*realms)) {
1382 ret = ERANGE;
1383 goto free_realms;
1385 tmp = realloc(realms, (num_realms + 1) * sizeof(*realms));
1386 if(tmp == NULL){
1387 ret = ENOMEM;
1388 goto free_realms;
1390 realms = tmp;
1391 realms[num_realms] = strdup(tgt_realm);
1392 if(realms[num_realms] == NULL){
1393 ret = ENOMEM;
1394 goto free_realms;
1396 num_realms++;
1398 if(num_realms == 0) {
1399 if(strcmp(client_realm, server_realm))
1400 kdc_log(0, "cross-realm %s -> %s", client_realm, server_realm);
1401 } else {
1402 size_t l = 0;
1403 char *rs;
1404 for(i = 0; i < num_realms; i++)
1405 l += strlen(realms[i]) + 2;
1406 rs = malloc(l);
1407 if(rs != NULL) {
1408 *rs = '\0';
1409 for(i = 0; i < num_realms; i++) {
1410 if(i > 0)
1411 strlcat(rs, ", ", l);
1412 strlcat(rs, realms[i], l);
1414 kdc_log(0, "cross-realm %s -> %s via [%s]", client_realm, server_realm, rs);
1415 free(rs);
1418 if(check_policy) {
1419 ret = krb5_check_transited(context, client_realm,
1420 server_realm,
1421 realms, num_realms, NULL);
1422 if(ret) {
1423 krb5_warn(context, ret, "cross-realm %s -> %s",
1424 client_realm, server_realm);
1425 goto free_realms;
1427 et->flags.transited_policy_checked = 1;
1429 et->transited.tr_type = DOMAIN_X500_COMPRESS;
1430 ret = krb5_domain_x500_encode(realms, num_realms, &et->transited.contents);
1431 if(ret)
1432 krb5_warn(context, ret, "Encoding transited encoding");
1433 free_realms:
1434 for(i = 0; i < num_realms; i++)
1435 free(realms[i]);
1436 free(realms);
1437 return ret;
1441 static krb5_error_code
1442 tgs_make_reply(KDC_REQ_BODY *b,
1443 EncTicketPart *tgt,
1444 EncTicketPart *adtkt,
1445 AuthorizationData *auth_data,
1446 hdb_entry *server,
1447 hdb_entry *client,
1448 krb5_principal client_principal,
1449 hdb_entry *krbtgt,
1450 krb5_enctype cetype,
1451 const char **e_text,
1452 krb5_data *reply)
1454 KDC_REP rep;
1455 EncKDCRepPart ek;
1456 EncTicketPart et;
1457 KDCOptions f = b->kdc_options;
1458 krb5_error_code ret;
1459 krb5_enctype etype;
1460 Key *skey;
1461 EncryptionKey *ekey;
1463 if(adtkt) {
1464 int i;
1465 krb5_keytype kt;
1466 ekey = &adtkt->key;
1467 for(i = 0; i < b->etype.len; i++){
1468 ret = krb5_enctype_to_keytype(context, b->etype.val[i], &kt);
1469 if(ret)
1470 continue;
1471 if(adtkt->key.keytype == kt)
1472 break;
1474 if(i == b->etype.len)
1475 return KRB5KDC_ERR_ETYPE_NOSUPP;
1476 etype = b->etype.val[i];
1477 }else{
1478 ret = find_keys(NULL, server, NULL, NULL, &skey, &etype,
1479 b->etype.val, b->etype.len);
1480 if(ret) {
1481 kdc_log(0, "Server has no support for etypes");
1482 return ret;
1484 ekey = &skey->key;
1487 memset(&rep, 0, sizeof(rep));
1488 memset(&et, 0, sizeof(et));
1489 memset(&ek, 0, sizeof(ek));
1491 rep.pvno = 5;
1492 rep.msg_type = krb_tgs_rep;
1494 et.authtime = tgt->authtime;
1495 fix_time(&b->till);
1496 et.endtime = min(tgt->endtime, *b->till);
1497 ALLOC(et.starttime);
1498 *et.starttime = kdc_time;
1500 ret = check_tgs_flags(b, tgt, &et);
1501 if(ret)
1502 goto out;
1504 /* We should check the transited encoding if:
1505 1) the request doesn't ask not to be checked
1506 2) globally enforcing a check
1507 3) principal requires checking
1508 4) we allow non-check per-principal, but principal isn't marked as allowing this
1509 5) we don't globally allow this
1512 #define GLOBAL_FORCE_TRANSITED_CHECK (trpolicy == TRPOLICY_ALWAYS_CHECK)
1513 #define GLOBAL_ALLOW_PER_PRINCIPAL (trpolicy == TRPOLICY_ALLOW_PER_PRINCIPAL)
1514 #define GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK (trpolicy == TRPOLICY_ALWAYS_HONOUR_REQUEST)
1515 /* these will consult the database in future release */
1516 #define PRINCIPAL_FORCE_TRANSITED_CHECK(P) 0
1517 #define PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(P) 0
1519 ret = fix_transited_encoding(!f.disable_transited_check ||
1520 GLOBAL_FORCE_TRANSITED_CHECK ||
1521 PRINCIPAL_FORCE_TRANSITED_CHECK(server) ||
1522 !((GLOBAL_ALLOW_PER_PRINCIPAL &&
1523 PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(server)) ||
1524 GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK),
1525 &tgt->transited, &et,
1526 *krb5_princ_realm(context, client_principal),
1527 *krb5_princ_realm(context, server->principal),
1528 *krb5_princ_realm(context, krbtgt->principal));
1529 if(ret)
1530 goto out;
1532 copy_Realm(krb5_princ_realm(context, server->principal),
1533 &rep.ticket.realm);
1534 _krb5_principal2principalname(&rep.ticket.sname, server->principal);
1535 copy_Realm(&tgt->crealm, &rep.crealm);
1536 if (f.request_anonymous)
1537 make_anonymous_principalname (&tgt->cname);
1538 else
1539 copy_PrincipalName(&tgt->cname, &rep.cname);
1540 rep.ticket.tkt_vno = 5;
1542 ek.caddr = et.caddr;
1543 if(et.caddr == NULL)
1544 et.caddr = tgt->caddr;
1547 time_t life;
1548 life = et.endtime - *et.starttime;
1549 if(client && client->max_life)
1550 life = min(life, *client->max_life);
1551 if(server->max_life)
1552 life = min(life, *server->max_life);
1553 et.endtime = *et.starttime + life;
1555 if(f.renewable_ok && tgt->flags.renewable &&
1556 et.renew_till == NULL && et.endtime < *b->till){
1557 et.flags.renewable = 1;
1558 ALLOC(et.renew_till);
1559 *et.renew_till = *b->till;
1561 if(et.renew_till){
1562 time_t renew;
1563 renew = *et.renew_till - et.authtime;
1564 if(client && client->max_renew)
1565 renew = min(renew, *client->max_renew);
1566 if(server->max_renew)
1567 renew = min(renew, *server->max_renew);
1568 *et.renew_till = et.authtime + renew;
1571 if(et.renew_till){
1572 *et.renew_till = min(*et.renew_till, *tgt->renew_till);
1573 *et.starttime = min(*et.starttime, *et.renew_till);
1574 et.endtime = min(et.endtime, *et.renew_till);
1577 *et.starttime = min(*et.starttime, et.endtime);
1579 if(*et.starttime == et.endtime){
1580 ret = KRB5KDC_ERR_NEVER_VALID;
1581 goto out;
1583 if(et.renew_till && et.endtime == *et.renew_till){
1584 free(et.renew_till);
1585 et.renew_till = NULL;
1586 et.flags.renewable = 0;
1589 et.flags.pre_authent = tgt->flags.pre_authent;
1590 et.flags.hw_authent = tgt->flags.hw_authent;
1591 et.flags.anonymous = tgt->flags.anonymous;
1592 et.flags.ok_as_delegate = server->flags.ok_as_delegate;
1594 /* XXX Check enc-authorization-data */
1595 et.authorization_data = auth_data;
1597 krb5_generate_random_keyblock(context, etype, &et.key);
1598 et.crealm = tgt->crealm;
1599 et.cname = tgt->cname;
1601 ek.key = et.key;
1602 /* MIT must have at least one last_req */
1603 ek.last_req.len = 1;
1604 ek.last_req.val = calloc(1, sizeof(*ek.last_req.val));
1605 ek.nonce = b->nonce;
1606 ek.flags = et.flags;
1607 ek.authtime = et.authtime;
1608 ek.starttime = et.starttime;
1609 ek.endtime = et.endtime;
1610 ek.renew_till = et.renew_till;
1611 ek.srealm = rep.ticket.realm;
1612 ek.sname = rep.ticket.sname;
1614 /* It is somewhat unclear where the etype in the following
1615 encryption should come from. What we have is a session
1616 key in the passed tgt, and a list of preferred etypes
1617 *for the new ticket*. Should we pick the best possible
1618 etype, given the keytype in the tgt, or should we look
1619 at the etype list here as well? What if the tgt
1620 session key is DES3 and we want a ticket with a (say)
1621 CAST session key. Should the DES3 etype be added to the
1622 etype list, even if we don't want a session key with
1623 DES3? */
1624 ret = encode_reply(&rep, &et, &ek, etype, adtkt ? 0 : server->kvno, ekey,
1625 0, &tgt->key, e_text, reply);
1626 out:
1627 free_TGS_REP(&rep);
1628 free_TransitedEncoding(&et.transited);
1629 if(et.starttime)
1630 free(et.starttime);
1631 if(et.renew_till)
1632 free(et.renew_till);
1633 free_LastReq(&ek.last_req);
1634 memset(et.key.keyvalue.data, 0, et.key.keyvalue.length);
1635 free_EncryptionKey(&et.key);
1636 return ret;
1639 static krb5_error_code
1640 tgs_check_authenticator(krb5_auth_context ac,
1641 KDC_REQ_BODY *b,
1642 const char **e_text,
1643 krb5_keyblock *key)
1645 krb5_authenticator auth;
1646 size_t len;
1647 unsigned char *buf;
1648 size_t buf_size;
1649 krb5_error_code ret;
1650 krb5_crypto crypto;
1652 krb5_auth_con_getauthenticator(context, ac, &auth);
1653 if(auth->cksum == NULL){
1654 kdc_log(0, "No authenticator in request");
1655 ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
1656 goto out;
1659 * according to RFC1510 it doesn't need to be keyed,
1660 * but according to the latest draft it needs to.
1662 if (
1663 #if 0
1664 !krb5_checksum_is_keyed(context, auth->cksum->cksumtype)
1666 #endif
1667 !krb5_checksum_is_collision_proof(context, auth->cksum->cksumtype)) {
1668 kdc_log(0, "Bad checksum type in authenticator: %d",
1669 auth->cksum->cksumtype);
1670 ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
1671 goto out;
1674 /* XXX should not re-encode this */
1675 ASN1_MALLOC_ENCODE(KDC_REQ_BODY, buf, buf_size, b, &len, ret);
1676 if(ret){
1677 kdc_log(0, "Failed to encode KDC-REQ-BODY: %s",
1678 krb5_get_err_text(context, ret));
1679 goto out;
1681 if(buf_size != len) {
1682 free(buf);
1683 kdc_log(0, "Internal error in ASN.1 encoder");
1684 *e_text = "KDC internal error";
1685 ret = KRB5KRB_ERR_GENERIC;
1686 goto out;
1688 ret = krb5_crypto_init(context, key, 0, &crypto);
1689 if (ret) {
1690 free(buf);
1691 kdc_log(0, "krb5_crypto_init failed: %s",
1692 krb5_get_err_text(context, ret));
1693 goto out;
1695 ret = krb5_verify_checksum(context,
1696 crypto,
1697 KRB5_KU_TGS_REQ_AUTH_CKSUM,
1698 buf,
1699 len,
1700 auth->cksum);
1701 free(buf);
1702 krb5_crypto_destroy(context, crypto);
1703 if(ret){
1704 kdc_log(0, "Failed to verify checksum: %s",
1705 krb5_get_err_text(context, ret));
1707 out:
1708 free_Authenticator(auth);
1709 free(auth);
1710 return ret;
1714 * return the realm of a krbtgt-ticket or NULL
1717 static Realm
1718 get_krbtgt_realm(const PrincipalName *p)
1720 if(p->name_string.len == 2
1721 && strcmp(p->name_string.val[0], KRB5_TGS_NAME) == 0)
1722 return p->name_string.val[1];
1723 else
1724 return NULL;
1727 static Realm
1728 find_rpath(Realm crealm, Realm srealm)
1730 const char *new_realm = krb5_config_get_string(context,
1731 NULL,
1732 "capaths",
1733 crealm,
1734 srealm,
1735 NULL);
1736 return (Realm)new_realm;
1740 static krb5_boolean
1741 need_referral(krb5_principal server, krb5_realm **realms)
1743 if(server->name.name_type != KRB5_NT_SRV_INST ||
1744 server->name.name_string.len != 2)
1745 return FALSE;
1747 return _krb5_get_host_realm_int(context, server->name.name_string.val[1],
1748 FALSE, realms) == 0;
1751 static krb5_error_code
1752 tgs_rep2(KDC_REQ_BODY *b,
1753 PA_DATA *tgs_req,
1754 krb5_data *reply,
1755 const char *from,
1756 const struct sockaddr *from_addr,
1757 time_t **csec,
1758 int **cusec)
1760 krb5_ap_req ap_req;
1761 krb5_error_code ret;
1762 krb5_principal princ;
1763 krb5_auth_context ac = NULL;
1764 krb5_ticket *ticket = NULL;
1765 krb5_flags ap_req_options;
1766 krb5_flags verify_ap_req_flags;
1767 const char *e_text = NULL;
1768 krb5_crypto crypto;
1770 hdb_entry *krbtgt = NULL;
1771 EncTicketPart *tgt;
1772 Key *tkey;
1773 krb5_enctype cetype;
1774 krb5_principal cp = NULL;
1775 krb5_principal sp = NULL;
1776 AuthorizationData *auth_data = NULL;
1778 *csec = NULL;
1779 *cusec = NULL;
1781 memset(&ap_req, 0, sizeof(ap_req));
1782 ret = krb5_decode_ap_req(context, &tgs_req->padata_value, &ap_req);
1783 if(ret){
1784 kdc_log(0, "Failed to decode AP-REQ: %s",
1785 krb5_get_err_text(context, ret));
1786 goto out2;
1789 if(!get_krbtgt_realm(&ap_req.ticket.sname)){
1790 /* XXX check for ticket.sname == req.sname */
1791 kdc_log(0, "PA-DATA is not a ticket-granting ticket");
1792 ret = KRB5KDC_ERR_POLICY; /* ? */
1793 goto out2;
1796 _krb5_principalname2krb5_principal(&princ,
1797 ap_req.ticket.sname,
1798 ap_req.ticket.realm);
1800 ret = db_fetch(princ, &krbtgt);
1802 if(ret) {
1803 char *p;
1804 ret = krb5_unparse_name(context, princ, &p);
1805 if (ret != 0)
1806 p = "<unparse_name failed>";
1807 krb5_free_principal(context, princ);
1808 kdc_log(0, "Ticket-granting ticket not found in database: %s: %s",
1809 p, krb5_get_err_text(context, ret));
1810 if (ret == 0)
1811 free(p);
1812 ret = KRB5KRB_AP_ERR_NOT_US;
1813 goto out2;
1816 if(ap_req.ticket.enc_part.kvno &&
1817 *ap_req.ticket.enc_part.kvno != krbtgt->kvno){
1818 char *p;
1820 ret = krb5_unparse_name (context, princ, &p);
1821 krb5_free_principal(context, princ);
1822 if (ret != 0)
1823 p = "<unparse_name failed>";
1824 kdc_log(0, "Ticket kvno = %d, DB kvno = %d (%s)",
1825 *ap_req.ticket.enc_part.kvno,
1826 krbtgt->kvno,
1828 if (ret == 0)
1829 free (p);
1830 ret = KRB5KRB_AP_ERR_BADKEYVER;
1831 goto out2;
1834 ret = hdb_enctype2key(context, krbtgt, ap_req.ticket.enc_part.etype, &tkey);
1835 if(ret){
1836 char *str;
1837 krb5_enctype_to_string(context, ap_req.ticket.enc_part.etype, &str);
1838 kdc_log(0, "No server key found for %s", str);
1839 free(str);
1840 ret = KRB5KRB_AP_ERR_BADKEYVER;
1841 goto out2;
1844 if (b->kdc_options.validate)
1845 verify_ap_req_flags = KRB5_VERIFY_AP_REQ_IGNORE_INVALID;
1846 else
1847 verify_ap_req_flags = 0;
1849 ret = krb5_verify_ap_req2(context,
1850 &ac,
1851 &ap_req,
1852 princ,
1853 &tkey->key,
1854 verify_ap_req_flags,
1855 &ap_req_options,
1856 &ticket,
1857 KRB5_KU_TGS_REQ_AUTH);
1859 krb5_free_principal(context, princ);
1860 if(ret) {
1861 kdc_log(0, "Failed to verify AP-REQ: %s",
1862 krb5_get_err_text(context, ret));
1863 goto out2;
1867 krb5_authenticator auth;
1869 ret = krb5_auth_con_getauthenticator(context, ac, &auth);
1870 if (ret == 0) {
1871 *csec = malloc(sizeof(**csec));
1872 if (*csec == NULL) {
1873 krb5_free_authenticator(context, &auth);
1874 kdc_log(0, "malloc failed");
1875 goto out2;
1877 **csec = auth->ctime;
1878 *cusec = malloc(sizeof(**cusec));
1879 if (*cusec == NULL) {
1880 krb5_free_authenticator(context, &auth);
1881 kdc_log(0, "malloc failed");
1882 goto out2;
1884 **csec = auth->cusec;
1885 krb5_free_authenticator(context, &auth);
1889 cetype = ap_req.authenticator.etype;
1891 tgt = &ticket->ticket;
1893 ret = tgs_check_authenticator(ac, b, &e_text, &tgt->key);
1895 if (b->enc_authorization_data) {
1896 krb5_keyblock *subkey;
1897 krb5_data ad;
1898 ret = krb5_auth_con_getremotesubkey(context,
1900 &subkey);
1901 if(ret){
1902 krb5_auth_con_free(context, ac);
1903 kdc_log(0, "Failed to get remote subkey: %s",
1904 krb5_get_err_text(context, ret));
1905 goto out2;
1907 if(subkey == NULL){
1908 ret = krb5_auth_con_getkey(context, ac, &subkey);
1909 if(ret) {
1910 krb5_auth_con_free(context, ac);
1911 kdc_log(0, "Failed to get session key: %s",
1912 krb5_get_err_text(context, ret));
1913 goto out2;
1916 if(subkey == NULL){
1917 krb5_auth_con_free(context, ac);
1918 kdc_log(0, "Failed to get key for enc-authorization-data");
1919 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
1920 goto out2;
1922 ret = krb5_crypto_init(context, subkey, 0, &crypto);
1923 if (ret) {
1924 krb5_auth_con_free(context, ac);
1925 kdc_log(0, "krb5_crypto_init failed: %s",
1926 krb5_get_err_text(context, ret));
1927 goto out2;
1929 ret = krb5_decrypt_EncryptedData (context,
1930 crypto,
1931 KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
1932 b->enc_authorization_data,
1933 &ad);
1934 krb5_crypto_destroy(context, crypto);
1935 if(ret){
1936 krb5_auth_con_free(context, ac);
1937 kdc_log(0, "Failed to decrypt enc-authorization-data");
1938 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
1939 goto out2;
1941 krb5_free_keyblock(context, subkey);
1942 ALLOC(auth_data);
1943 ret = decode_AuthorizationData(ad.data, ad.length, auth_data, NULL);
1944 if(ret){
1945 krb5_auth_con_free(context, ac);
1946 free(auth_data);
1947 auth_data = NULL;
1948 kdc_log(0, "Failed to decode authorization data");
1949 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
1950 goto out2;
1954 krb5_auth_con_free(context, ac);
1956 if(ret){
1957 kdc_log(0, "Failed to verify authenticator: %s",
1958 krb5_get_err_text(context, ret));
1959 goto out2;
1963 PrincipalName *s;
1964 Realm r;
1965 char *spn = NULL, *cpn = NULL;
1966 hdb_entry *server = NULL, *client = NULL;
1967 int loop = 0;
1968 EncTicketPart adtkt;
1969 char opt_str[128];
1971 s = b->sname;
1972 r = b->realm;
1973 if(b->kdc_options.enc_tkt_in_skey){
1974 Ticket *t;
1975 hdb_entry *uu;
1976 krb5_principal p;
1977 Key *tkey;
1979 if(b->additional_tickets == NULL ||
1980 b->additional_tickets->len == 0){
1981 ret = KRB5KDC_ERR_BADOPTION; /* ? */
1982 kdc_log(0, "No second ticket present in request");
1983 goto out;
1985 t = &b->additional_tickets->val[0];
1986 if(!get_krbtgt_realm(&t->sname)){
1987 kdc_log(0, "Additional ticket is not a ticket-granting ticket");
1988 ret = KRB5KDC_ERR_POLICY;
1989 goto out2;
1991 _krb5_principalname2krb5_principal(&p, t->sname, t->realm);
1992 ret = db_fetch(p, &uu);
1993 krb5_free_principal(context, p);
1994 if(ret){
1995 if (ret == HDB_ERR_NOENTRY)
1996 ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
1997 goto out;
1999 ret = hdb_enctype2key(context, uu, t->enc_part.etype, &tkey);
2000 if(ret){
2001 ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
2002 goto out;
2004 ret = krb5_decrypt_ticket(context, t, &tkey->key, &adtkt, 0);
2006 if(ret)
2007 goto out;
2008 s = &adtkt.cname;
2009 r = adtkt.crealm;
2012 _krb5_principalname2krb5_principal(&sp, *s, r);
2013 ret = krb5_unparse_name(context, sp, &spn);
2014 if (ret)
2015 goto out;
2016 _krb5_principalname2krb5_principal(&cp, tgt->cname, tgt->crealm);
2017 ret = krb5_unparse_name(context, cp, &cpn);
2018 if (ret)
2019 goto out;
2020 unparse_flags (KDCOptions2int(b->kdc_options),
2021 asn1_KDCOptions_units(),
2022 opt_str, sizeof(opt_str));
2023 if(*opt_str)
2024 kdc_log(0, "TGS-REQ %s from %s for %s [%s]",
2025 cpn, from, spn, opt_str);
2026 else
2027 kdc_log(0, "TGS-REQ %s from %s for %s", cpn, from, spn);
2028 server_lookup:
2029 ret = db_fetch(sp, &server);
2031 if(ret){
2032 Realm req_rlm, new_rlm;
2033 krb5_realm *realms;
2035 if ((req_rlm = get_krbtgt_realm(&sp->name)) != NULL) {
2036 if(loop++ < 2) {
2037 new_rlm = find_rpath(tgt->crealm, req_rlm);
2038 if(new_rlm) {
2039 kdc_log(5, "krbtgt for realm %s not found, trying %s",
2040 req_rlm, new_rlm);
2041 krb5_free_principal(context, sp);
2042 free(spn);
2043 krb5_make_principal(context, &sp, r,
2044 KRB5_TGS_NAME, new_rlm, NULL);
2045 ret = krb5_unparse_name(context, sp, &spn);
2046 if (ret)
2047 goto out;
2048 goto server_lookup;
2051 } else if(need_referral(sp, &realms)) {
2052 if (strcmp(realms[0], sp->realm) != 0) {
2053 kdc_log(5, "returning a referral to realm %s for "
2054 "server %s that was not found",
2055 realms[0], spn);
2056 krb5_free_principal(context, sp);
2057 free(spn);
2058 krb5_make_principal(context, &sp, r, KRB5_TGS_NAME,
2059 realms[0], NULL);
2060 ret = krb5_unparse_name(context, sp, &spn);
2061 if (ret)
2062 goto out;
2063 krb5_free_host_realm(context, realms);
2064 goto server_lookup;
2066 krb5_free_host_realm(context, realms);
2068 kdc_log(0, "Server not found in database: %s: %s", spn,
2069 krb5_get_err_text(context, ret));
2070 if (ret == HDB_ERR_NOENTRY)
2071 ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
2072 goto out;
2075 ret = db_fetch(cp, &client);
2076 if(ret)
2077 kdc_log(1, "Client not found in database: %s: %s",
2078 cpn, krb5_get_err_text(context, ret));
2079 #if 0
2080 /* XXX check client only if same realm as krbtgt-instance */
2081 if(ret){
2082 kdc_log(0, "Client not found in database: %s: %s",
2083 cpn, krb5_get_err_text(context, ret));
2084 if (ret == HDB_ERR_NOENTRY)
2085 ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
2086 goto out;
2088 #endif
2090 if(strcmp(krb5_principal_get_realm(context, sp),
2091 krb5_principal_get_comp_string(context, krbtgt->principal, 1)) != 0) {
2092 char *tpn;
2093 ret = krb5_unparse_name(context, krbtgt->principal, &tpn);
2094 kdc_log(0, "Request with wrong krbtgt: %s", (ret == 0) ? tpn : "<unknown>");
2095 if(ret == 0)
2096 free(tpn);
2097 ret = KRB5KRB_AP_ERR_NOT_US;
2098 goto out;
2102 ret = check_flags(client, cpn, server, spn, FALSE);
2103 if(ret)
2104 goto out;
2106 if((b->kdc_options.validate || b->kdc_options.renew) &&
2107 !krb5_principal_compare(context,
2108 krbtgt->principal,
2109 server->principal)){
2110 kdc_log(0, "Inconsistent request.");
2111 ret = KRB5KDC_ERR_SERVER_NOMATCH;
2112 goto out;
2115 /* check for valid set of addresses */
2116 if(!check_addresses(tgt->caddr, from_addr)) {
2117 ret = KRB5KRB_AP_ERR_BADADDR;
2118 kdc_log(0, "Request from wrong address");
2119 goto out;
2122 ret = tgs_make_reply(b,
2123 tgt,
2124 b->kdc_options.enc_tkt_in_skey ? &adtkt : NULL,
2125 auth_data,
2126 server,
2127 client,
2128 cp,
2129 krbtgt,
2130 cetype,
2131 &e_text,
2132 reply);
2134 out:
2135 free(spn);
2136 free(cpn);
2138 if(server)
2139 free_ent(server);
2140 if(client)
2141 free_ent(client);
2143 out2:
2144 if(ret) {
2145 krb5_mk_error(context,
2146 ret,
2147 e_text,
2148 NULL,
2151 NULL,
2152 NULL,
2153 reply);
2154 free(*csec);
2155 free(*cusec);
2156 *csec = NULL;
2157 *cusec = NULL;
2159 krb5_free_principal(context, cp);
2160 krb5_free_principal(context, sp);
2161 if (ticket)
2162 krb5_free_ticket(context, ticket);
2163 free_AP_REQ(&ap_req);
2164 if(auth_data){
2165 free_AuthorizationData(auth_data);
2166 free(auth_data);
2169 if(krbtgt)
2170 free_ent(krbtgt);
2172 return ret;
2176 krb5_error_code
2177 tgs_rep(KDC_REQ *req,
2178 krb5_data *data,
2179 const char *from,
2180 struct sockaddr *from_addr)
2182 krb5_error_code ret;
2183 int i = 0;
2184 PA_DATA *tgs_req = NULL;
2185 time_t *csec = NULL;
2186 int *cusec = NULL;
2188 if(req->padata == NULL){
2189 ret = KRB5KDC_ERR_PREAUTH_REQUIRED; /* XXX ??? */
2190 kdc_log(0, "TGS-REQ from %s without PA-DATA", from);
2191 goto out;
2194 tgs_req = find_padata(req, &i, KRB5_PADATA_TGS_REQ);
2196 if(tgs_req == NULL){
2197 ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
2199 kdc_log(0, "TGS-REQ from %s without PA-TGS-REQ", from);
2200 goto out;
2202 ret = tgs_rep2(&req->req_body, tgs_req, data, from, from_addr,
2203 &csec, &cusec);
2204 out:
2205 if(ret && data->data == NULL){
2206 krb5_mk_error(context,
2207 ret,
2208 NULL,
2209 NULL,
2210 NULL,
2211 NULL,
2212 csec,
2213 cusec,
2214 data);
2216 free(csec);
2217 free(cusec);
2218 return 0;