2 * Copyright (c) 1997-2003 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
36 RCSID("$Id: kerberos5.c,v 1.145.2.3 2003/12/14 19:43:04 lha Exp $");
38 #define MAX_TIME ((time_t)((1U << 31) - 1))
47 if(**t == 0) **t = MAX_TIME; /* fix for old clients */
51 set_salt_padata (METHOD_DATA **m, Salt *salt)
57 (*m)->val->padata_type = salt->type;
58 copy_octet_string(&salt->salt,
59 &(*m)->val->padata_value);
64 find_padata(KDC_REQ *req, int *start, int type)
66 while(*start < req->padata->len){
68 if(req->padata->val[*start - 1].padata_type == type)
69 return &req->padata->val[*start - 1];
75 * return the first appropriate key of `princ' in `ret_key'. Look for
76 * all the etypes in (`etypes', `len'), stopping as soon as we find
77 * one, but preferring one that has default salt
80 static krb5_error_code
81 find_etype(hdb_entry *princ, krb5_enctype *etypes, unsigned len,
82 Key **ret_key, krb5_enctype *ret_etype)
85 krb5_error_code ret = KRB5KDC_ERR_ETYPE_NOSUPP;
87 for(i = 0; ret != 0 && i < len ; i++) {
90 while (hdb_next_enctype2key(context, princ, etypes[i], &key) == 0) {
91 if (key->key.keyvalue.length == 0) {
92 ret = KRB5KDC_ERR_NULL_KEY;
96 *ret_etype = etypes[i];
98 if (key->salt == NULL)
105 static krb5_error_code
106 find_keys(hdb_entry *client,
109 krb5_enctype *cetype,
111 krb5_enctype *setype,
112 krb5_enctype *etypes,
118 /* find client key */
119 ret = find_etype(client, etypes, num_etypes, ckey, cetype);
121 kdc_log(0, "Client has no support for etypes");
127 /* find server key */
128 ret = find_etype(server, etypes, num_etypes, skey, setype);
130 kdc_log(0, "Server has no support for etypes");
137 static krb5_error_code
138 make_anonymous_principalname (PrincipalName *pn)
140 pn->name_type = KRB5_NT_PRINCIPAL;
141 pn->name_string.len = 1;
142 pn->name_string.val = malloc(sizeof(*pn->name_string.val));
143 if (pn->name_string.val == NULL)
145 pn->name_string.val[0] = strdup("anonymous");
146 if (pn->name_string.val[0] == NULL) {
147 free(pn->name_string.val);
148 pn->name_string.val = NULL;
154 static krb5_error_code
155 encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek,
157 int skvno, EncryptionKey *skey,
158 int ckvno, EncryptionKey *ckey,
168 ASN1_MALLOC_ENCODE(EncTicketPart, buf, buf_size, et, &len, ret);
170 kdc_log(0, "Failed to encode ticket: %s",
171 krb5_get_err_text(context, ret));
174 if(buf_size != len) {
176 kdc_log(0, "Internal error in ASN.1 encoder");
177 *e_text = "KDC internal error";
178 return KRB5KRB_ERR_GENERIC;
181 ret = krb5_crypto_init(context, skey, etype, &crypto);
184 kdc_log(0, "krb5_crypto_init failed: %s",
185 krb5_get_err_text(context, ret));
189 ret = krb5_encrypt_EncryptedData(context,
195 &rep->ticket.enc_part);
197 krb5_crypto_destroy(context, crypto);
199 kdc_log(0, "Failed to encrypt data: %s",
200 krb5_get_err_text(context, ret));
204 if(rep->msg_type == krb_as_rep && !encode_as_rep_as_tgs_rep)
205 ASN1_MALLOC_ENCODE(EncASRepPart, buf, buf_size, ek, &len, ret);
207 ASN1_MALLOC_ENCODE(EncTGSRepPart, buf, buf_size, ek, &len, ret);
209 kdc_log(0, "Failed to encode KDC-REP: %s",
210 krb5_get_err_text(context, ret));
213 if(buf_size != len) {
215 kdc_log(0, "Internal error in ASN.1 encoder");
216 *e_text = "KDC internal error";
217 return KRB5KRB_ERR_GENERIC;
219 ret = krb5_crypto_init(context, ckey, 0, &crypto);
222 kdc_log(0, "krb5_crypto_init failed: %s",
223 krb5_get_err_text(context, ret));
226 if(rep->msg_type == krb_as_rep) {
227 krb5_encrypt_EncryptedData(context,
229 KRB5_KU_AS_REP_ENC_PART,
235 ASN1_MALLOC_ENCODE(AS_REP, buf, buf_size, rep, &len, ret);
237 krb5_encrypt_EncryptedData(context,
239 KRB5_KU_TGS_REP_ENC_PART_SESSION,
245 ASN1_MALLOC_ENCODE(TGS_REP, buf, buf_size, rep, &len, ret);
247 krb5_crypto_destroy(context, crypto);
249 kdc_log(0, "Failed to encode KDC-REP: %s",
250 krb5_get_err_text(context, ret));
253 if(buf_size != len) {
255 kdc_log(0, "Internal error in ASN.1 encoder");
256 *e_text = "KDC internal error";
257 return KRB5KRB_ERR_GENERIC;
260 reply->length = buf_size;
265 realloc_method_data(METHOD_DATA *md)
268 pa = realloc(md->val, (md->len + 1) * sizeof(*md->val));
276 static krb5_error_code
277 make_etype_info_entry(ETYPE_INFO_ENTRY *ent, Key *key)
279 ent->etype = key->key.keytype;
281 ALLOC(ent->salttype);
283 if(key->salt->type == hdb_pw_salt)
284 *ent->salttype = 0; /* or 1? or NULL? */
285 else if(key->salt->type == hdb_afs3_salt)
288 kdc_log(0, "unknown salt-type: %d",
290 return KRB5KRB_ERR_GENERIC;
292 /* according to `the specs', we can't send a salt if
293 we have AFS3 salted key, but that requires that you
294 *know* what cell you are using (e.g by assuming
295 that the cell is the same as the realm in lower
298 *ent->salttype = key->salt->type;
300 krb5_copy_data(context, &key->salt->salt,
303 /* we return no salt type at all, as that should indicate
304 * the default salt type and make everybody happy. some
305 * systems (like w2k) dislike being told the salt type
308 ent->salttype = NULL;
314 static krb5_error_code
315 get_pa_etype_info(METHOD_DATA *md, hdb_entry *client,
316 ENCTYPE *etypes, unsigned int etypes_len)
318 krb5_error_code ret = 0;
326 pa.len = client->keys.len;
327 if(pa.len > UINT_MAX/sizeof(*pa.val))
329 pa.val = malloc(pa.len * sizeof(*pa.val));
333 for(j = 0; j < etypes_len; j++) {
334 for(i = 0; i < client->keys.len; i++) {
335 if(client->keys.val[i].key.keytype == etypes[j])
336 if((ret = make_etype_info_entry(&pa.val[n++],
337 &client->keys.val[i])) != 0) {
338 free_ETYPE_INFO(&pa);
343 for(i = 0; i < client->keys.len; i++) {
344 for(j = 0; j < etypes_len; j++) {
345 if(client->keys.val[i].key.keytype == etypes[j])
348 if((ret = make_etype_info_entry(&pa.val[n++],
349 &client->keys.val[i])) != 0) {
350 free_ETYPE_INFO(&pa);
358 krb5_unparse_name(context, client->principal, &name);
359 kdc_log(0, "internal error in get_pa_etype_info(%s): %d != %d",
365 ASN1_MALLOC_ENCODE(ETYPE_INFO, buf, len, &pa, &len, ret);
366 free_ETYPE_INFO(&pa);
369 ret = realloc_method_data(md);
374 md->val[md->len - 1].padata_type = KRB5_PADATA_ETYPE_INFO;
375 md->val[md->len - 1].padata_value.length = len;
376 md->val[md->len - 1].padata_value.data = buf;
381 * verify the flags on `client' and `server', returning 0
382 * if they are OK and generating an error messages and returning
383 * and error code otherwise.
387 check_flags(hdb_entry *client, const char *client_name,
388 hdb_entry *server, const char *server_name,
389 krb5_boolean is_as_req)
393 if (client->flags.invalid) {
394 kdc_log(0, "Client (%s) has invalid bit set", client_name);
395 return KRB5KDC_ERR_POLICY;
398 if(!client->flags.client){
399 kdc_log(0, "Principal may not act as client -- %s",
401 return KRB5KDC_ERR_POLICY;
404 if (client->valid_start && *client->valid_start > kdc_time) {
405 kdc_log(0, "Client not yet valid -- %s", client_name);
406 return KRB5KDC_ERR_CLIENT_NOTYET;
409 if (client->valid_end && *client->valid_end < kdc_time) {
410 kdc_log(0, "Client expired -- %s", client_name);
411 return KRB5KDC_ERR_NAME_EXP;
414 if (client->pw_end && *client->pw_end < kdc_time
415 && !server->flags.change_pw) {
416 kdc_log(0, "Client's key has expired -- %s", client_name);
417 return KRB5KDC_ERR_KEY_EXPIRED;
423 if (server != NULL) {
424 if (server->flags.invalid) {
425 kdc_log(0, "Server has invalid flag set -- %s", server_name);
426 return KRB5KDC_ERR_POLICY;
429 if(!server->flags.server){
430 kdc_log(0, "Principal may not act as server -- %s",
432 return KRB5KDC_ERR_POLICY;
435 if(!is_as_req && server->flags.initial) {
436 kdc_log(0, "AS-REQ is required for server -- %s", server_name);
437 return KRB5KDC_ERR_POLICY;
440 if (server->valid_start && *server->valid_start > kdc_time) {
441 kdc_log(0, "Server not yet valid -- %s", server_name);
442 return KRB5KDC_ERR_SERVICE_NOTYET;
445 if (server->valid_end && *server->valid_end < kdc_time) {
446 kdc_log(0, "Server expired -- %s", server_name);
447 return KRB5KDC_ERR_SERVICE_EXP;
450 if (server->pw_end && *server->pw_end < kdc_time) {
451 kdc_log(0, "Server's key has expired -- %s", server_name);
452 return KRB5KDC_ERR_KEY_EXPIRED;
459 * Return TRUE if `from' is part of `addresses' taking into consideration
460 * the configuration variables that tells us how strict we should be about
465 check_addresses(HostAddresses *addresses, const struct sockaddr *from)
471 if(check_ticket_addresses == 0)
474 if(addresses == NULL)
475 return allow_null_ticket_addresses;
477 ret = krb5_sockaddr2address (context, from, &addr);
481 result = krb5_address_search(context, &addr, addresses);
482 krb5_free_address (context, &addr);
490 struct sockaddr *from_addr)
492 KDC_REQ_BODY *b = &req->req_body;
494 KDCOptions f = b->kdc_options;
495 hdb_entry *client = NULL, *server = NULL;
496 krb5_enctype cetype, setype;
499 krb5_principal client_princ = NULL, server_princ = NULL;
500 char *client_name = NULL, *server_name = NULL;
501 krb5_error_code ret = 0;
502 const char *e_text = NULL;
506 memset(&rep, 0, sizeof(rep));
508 if(b->sname == NULL){
509 ret = KRB5KRB_ERR_GENERIC;
510 e_text = "No server in request";
512 principalname2krb5_principal (&server_princ, *(b->sname), b->realm);
513 krb5_unparse_name(context, server_princ, &server_name);
516 kdc_log(0, "AS-REQ malformed server name from %s", from);
520 if(b->cname == NULL){
521 ret = KRB5KRB_ERR_GENERIC;
522 e_text = "No client in request";
524 principalname2krb5_principal (&client_princ, *(b->cname), b->realm);
525 krb5_unparse_name(context, client_princ, &client_name);
528 kdc_log(0, "AS-REQ malformed client name from %s", from);
532 kdc_log(0, "AS-REQ %s from %s for %s", client_name, from, server_name);
534 ret = db_fetch(client_princ, &client);
536 kdc_log(0, "UNKNOWN -- %s: %s", client_name,
537 krb5_get_err_text(context, ret));
538 ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
542 ret = db_fetch(server_princ, &server);
544 kdc_log(0, "UNKNOWN -- %s: %s", server_name,
545 krb5_get_err_text(context, ret));
546 ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
550 ret = check_flags(client, client_name, server, server_name, TRUE);
554 memset(&et, 0, sizeof(et));
555 memset(&ek, 0, sizeof(ek));
561 kdc_log(5, "Looking for pa-data -- %s", client_name);
562 while((pa = find_padata(req, &i, KRB5_PADATA_ENC_TIMESTAMP))){
567 EncryptedData enc_data;
572 ret = decode_EncryptedData(pa->padata_value.data,
573 pa->padata_value.length,
577 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
578 kdc_log(5, "Failed to decode PA-DATA -- %s",
583 ret = hdb_enctype2key(context, client, enc_data.etype, &pa_key);
586 e_text = "No key matches pa-data";
587 ret = KRB5KDC_ERR_PREAUTH_FAILED;
588 if(krb5_enctype_to_string(context, enc_data.etype, &estr))
591 kdc_log(5, "No client key matching pa-data (%d) -- %s",
592 enc_data.etype, client_name);
594 kdc_log(5, "No client key matching pa-data (%s) -- %s",
598 free_EncryptedData(&enc_data);
603 ret = krb5_crypto_init(context, &pa_key->key, 0, &crypto);
605 kdc_log(0, "krb5_crypto_init failed: %s",
606 krb5_get_err_text(context, ret));
607 free_EncryptedData(&enc_data);
611 ret = krb5_decrypt_EncryptedData (context,
613 KRB5_KU_PA_ENC_TIMESTAMP,
616 krb5_crypto_destroy(context, crypto);
618 if(hdb_next_enctype2key(context, client,
619 enc_data.etype, &pa_key) == 0)
621 free_EncryptedData(&enc_data);
622 e_text = "Failed to decrypt PA-DATA";
623 kdc_log (5, "Failed to decrypt PA-DATA -- %s",
625 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
628 free_EncryptedData(&enc_data);
629 ret = decode_PA_ENC_TS_ENC(ts_data.data,
633 krb5_data_free(&ts_data);
635 e_text = "Failed to decode PA-ENC-TS-ENC";
636 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
637 kdc_log (5, "Failed to decode PA-ENC-TS_ENC -- %s",
641 patime = p.patimestamp;
642 free_PA_ENC_TS_ENC(&p);
643 if (abs(kdc_time - p.patimestamp) > context->max_skew) {
644 ret = KRB5KDC_ERR_PREAUTH_FAILED;
645 e_text = "Too large time skew";
646 kdc_log(0, "Too large time skew -- %s", client_name);
649 et.flags.pre_authent = 1;
650 kdc_log(2, "Pre-authentication succeded -- %s", client_name);
653 if(found_pa == 0 && require_preauth)
655 /* We come here if we found a pa-enc-timestamp, but if there
656 was some problem with it, other than too large skew */
657 if(found_pa && et.flags.pre_authent == 0){
658 kdc_log(0, "%s -- %s", e_text, client_name);
662 }else if (require_preauth
663 || client->flags.require_preauth
664 || server->flags.require_preauth) {
665 METHOD_DATA method_data;
673 method_data.val = NULL;
675 ret = realloc_method_data(&method_data);
676 pa = &method_data.val[method_data.len-1];
677 pa->padata_type = KRB5_PADATA_ENC_TIMESTAMP;
678 pa->padata_value.length = 0;
679 pa->padata_value.data = NULL;
681 ret = get_pa_etype_info(&method_data, client,
682 b->etype.val, b->etype.len); /* XXX check ret */
684 ASN1_MALLOC_ENCODE(METHOD_DATA, buf, len, &method_data, &len, ret);
685 free_METHOD_DATA(&method_data);
687 foo_data.length = len;
689 ret = KRB5KDC_ERR_PREAUTH_REQUIRED;
690 krb5_mk_error(context,
692 "Need to use PA-ENC-TIMESTAMP",
700 kdc_log(0, "No PA-ENC-TIMESTAMP -- %s", client_name);
705 ret = find_keys(client, server, &ckey, &cetype, &skey, &setype,
706 b->etype.val, b->etype.len);
708 kdc_log(0, "Server/client has no support for etypes");
716 ret = krb5_enctype_to_string(context, cetype, &cet);
718 ret = krb5_enctype_to_string(context, setype, &set);
720 kdc_log(5, "Using %s/%s", cet, set);
726 kdc_log(5, "Using e-types %d/%d", cetype, setype);
731 unparse_flags(KDCOptions2int(f), KDCOptions_units, str, sizeof(str));
733 kdc_log(2, "Requested flags: %s", str);
737 if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey
738 || (f.request_anonymous && !allow_anonymous)) {
739 ret = KRB5KDC_ERR_BADOPTION;
740 kdc_log(0, "Bad KDC options -- %s", client_name);
745 rep.msg_type = krb_as_rep;
746 copy_Realm(&b->realm, &rep.crealm);
747 if (f.request_anonymous)
748 make_anonymous_principalname (&rep.cname);
750 copy_PrincipalName(b->cname, &rep.cname);
751 rep.ticket.tkt_vno = 5;
752 copy_Realm(&b->realm, &rep.ticket.realm);
753 copy_PrincipalName(b->sname, &rep.ticket.sname);
755 et.flags.initial = 1;
756 if(client->flags.forwardable && server->flags.forwardable)
757 et.flags.forwardable = f.forwardable;
758 else if (f.forwardable) {
759 ret = KRB5KDC_ERR_POLICY;
760 kdc_log(0, "Ticket may not be forwardable -- %s", client_name);
763 if(client->flags.proxiable && server->flags.proxiable)
764 et.flags.proxiable = f.proxiable;
765 else if (f.proxiable) {
766 ret = KRB5KDC_ERR_POLICY;
767 kdc_log(0, "Ticket may not be proxiable -- %s", client_name);
770 if(client->flags.postdate && server->flags.postdate)
771 et.flags.may_postdate = f.allow_postdate;
772 else if (f.allow_postdate){
773 ret = KRB5KDC_ERR_POLICY;
774 kdc_log(0, "Ticket may not be postdatable -- %s", client_name);
778 /* check for valid set of addresses */
779 if(!check_addresses(b->addresses, from_addr)) {
780 ret = KRB5KRB_AP_ERR_BADADDR;
781 kdc_log(0, "Bad address list requested -- %s", client_name);
785 krb5_generate_random_keyblock(context, setype, &et.key);
786 copy_PrincipalName(&rep.cname, &et.cname);
787 copy_Realm(&b->realm, &et.crealm);
793 start = et.authtime = kdc_time;
795 if(f.postdated && req->req_body.from){
797 start = *et.starttime = *req->req_body.from;
798 et.flags.invalid = 1;
799 et.flags.postdated = 1; /* XXX ??? */
804 /* be careful not overflowing */
807 t = start + min(t - start, *client->max_life);
809 t = start + min(t - start, *server->max_life);
811 t = min(t, start + realm->max_life);
814 if(f.renewable_ok && et.endtime < *b->till){
816 if(b->rtime == NULL){
820 if(*b->rtime < *b->till)
821 *b->rtime = *b->till;
823 if(f.renewable && b->rtime){
827 if(client->max_renew)
828 t = start + min(t - start, *client->max_renew);
829 if(server->max_renew)
830 t = start + min(t - start, *server->max_renew);
832 t = min(t, start + realm->max_renew);
834 ALLOC(et.renew_till);
836 et.flags.renewable = 1;
840 if (f.request_anonymous)
841 et.flags.anonymous = 1;
845 copy_HostAddresses(b->addresses, et.caddr);
848 et.transited.tr_type = DOMAIN_X500_COMPRESS;
849 krb5_data_zero(&et.transited.contents);
851 copy_EncryptionKey(&et.key, &ek.key);
853 /* The MIT ASN.1 library (obviously) doesn't tell lengths encoded
854 * as 0 and as 0x80 (meaning indefinite length) apart, and is thus
855 * incapable of correctly decoding SEQUENCE OF's of zero length.
857 * To fix this, always send at least one no-op last_req
859 * If there's a pw_end or valid_end we will use that,
860 * otherwise just a dummy lr.
862 ek.last_req.val = malloc(2 * sizeof(*ek.last_req.val));
865 && (kdc_warn_pwexpire == 0
866 || kdc_time + kdc_warn_pwexpire <= *client->pw_end)) {
867 ek.last_req.val[ek.last_req.len].lr_type = LR_PW_EXPTIME;
868 ek.last_req.val[ek.last_req.len].lr_value = *client->pw_end;
871 if (client->valid_end) {
872 ek.last_req.val[ek.last_req.len].lr_type = LR_ACCT_EXPTIME;
873 ek.last_req.val[ek.last_req.len].lr_value = *client->valid_end;
876 if (ek.last_req.len == 0) {
877 ek.last_req.val[ek.last_req.len].lr_type = LR_NONE;
878 ek.last_req.val[ek.last_req.len].lr_value = 0;
882 if (client->valid_end || client->pw_end) {
883 ALLOC(ek.key_expiration);
884 if (client->valid_end) {
886 *ek.key_expiration = min(*client->valid_end, *client->pw_end);
888 *ek.key_expiration = *client->valid_end;
890 *ek.key_expiration = *client->pw_end;
892 ek.key_expiration = NULL;
894 ek.authtime = et.authtime;
897 *ek.starttime = *et.starttime;
899 ek.endtime = et.endtime;
901 ALLOC(ek.renew_till);
902 *ek.renew_till = *et.renew_till;
904 copy_Realm(&rep.ticket.realm, &ek.srealm);
905 copy_PrincipalName(&rep.ticket.sname, &ek.sname);
908 copy_HostAddresses(et.caddr, ek.caddr);
911 set_salt_padata (&rep.padata, ckey->salt);
912 ret = encode_reply(&rep, &et, &ek, setype, server->kvno, &skey->key,
913 client->kvno, &ckey->key, &e_text, reply);
914 free_EncTicketPart(&et);
915 free_EncKDCRepPart(&ek);
919 krb5_mk_error(context,
932 krb5_free_principal(context, client_princ);
935 krb5_free_principal(context, server_princ);
945 static krb5_error_code
946 check_tgs_flags(KDC_REQ_BODY *b, EncTicketPart *tgt, EncTicketPart *et)
948 KDCOptions f = b->kdc_options;
951 if(!tgt->flags.invalid || tgt->starttime == NULL){
952 kdc_log(0, "Bad request to validate ticket");
953 return KRB5KDC_ERR_BADOPTION;
955 if(*tgt->starttime > kdc_time){
956 kdc_log(0, "Early request to validate ticket");
957 return KRB5KRB_AP_ERR_TKT_NYV;
960 et->flags.invalid = 0;
961 }else if(tgt->flags.invalid){
962 kdc_log(0, "Ticket-granting ticket has INVALID flag set");
963 return KRB5KRB_AP_ERR_TKT_INVALID;
967 if(!tgt->flags.forwardable){
968 kdc_log(0, "Bad request for forwardable ticket");
969 return KRB5KDC_ERR_BADOPTION;
971 et->flags.forwardable = 1;
974 if(!tgt->flags.forwardable){
975 kdc_log(0, "Request to forward non-forwardable ticket");
976 return KRB5KDC_ERR_BADOPTION;
978 et->flags.forwarded = 1;
979 et->caddr = b->addresses;
981 if(tgt->flags.forwarded)
982 et->flags.forwarded = 1;
985 if(!tgt->flags.proxiable){
986 kdc_log(0, "Bad request for proxiable ticket");
987 return KRB5KDC_ERR_BADOPTION;
989 et->flags.proxiable = 1;
992 if(!tgt->flags.proxiable){
993 kdc_log(0, "Request to proxy non-proxiable ticket");
994 return KRB5KDC_ERR_BADOPTION;
997 et->caddr = b->addresses;
1000 et->flags.proxy = 1;
1002 if(f.allow_postdate){
1003 if(!tgt->flags.may_postdate){
1004 kdc_log(0, "Bad request for post-datable ticket");
1005 return KRB5KDC_ERR_BADOPTION;
1007 et->flags.may_postdate = 1;
1010 if(!tgt->flags.may_postdate){
1011 kdc_log(0, "Bad request for postdated ticket");
1012 return KRB5KDC_ERR_BADOPTION;
1015 *et->starttime = *b->from;
1016 et->flags.postdated = 1;
1017 et->flags.invalid = 1;
1018 }else if(b->from && *b->from > kdc_time + context->max_skew){
1019 kdc_log(0, "Ticket cannot be postdated");
1020 return KRB5KDC_ERR_CANNOT_POSTDATE;
1024 if(!tgt->flags.renewable){
1025 kdc_log(0, "Bad request for renewable ticket");
1026 return KRB5KDC_ERR_BADOPTION;
1028 et->flags.renewable = 1;
1029 ALLOC(et->renew_till);
1030 fix_time(&b->rtime);
1031 *et->renew_till = *b->rtime;
1035 if(!tgt->flags.renewable || tgt->renew_till == NULL){
1036 kdc_log(0, "Request to renew non-renewable ticket");
1037 return KRB5KDC_ERR_BADOPTION;
1039 old_life = tgt->endtime;
1041 old_life -= *tgt->starttime;
1043 old_life -= tgt->authtime;
1044 et->endtime = *et->starttime + old_life;
1045 if (et->renew_till != NULL)
1046 et->endtime = min(*et->renew_till, et->endtime);
1049 /* checks for excess flags */
1050 if(f.request_anonymous && !allow_anonymous){
1051 kdc_log(0, "Request for anonymous ticket");
1052 return KRB5KDC_ERR_BADOPTION;
1057 static krb5_error_code
1058 fix_transited_encoding(krb5_boolean check_policy,
1059 TransitedEncoding *tr,
1061 const char *client_realm,
1062 const char *server_realm,
1063 const char *tgt_realm)
1065 krb5_error_code ret = 0;
1066 char **realms, **tmp;
1070 if(tr->tr_type != DOMAIN_X500_COMPRESS) {
1071 kdc_log(0, "Unknown transited type: %u", tr->tr_type);
1072 return KRB5KDC_ERR_TRTYPE_NOSUPP;
1075 ret = krb5_domain_x500_decode(context,
1082 krb5_warn(context, ret, "Decoding transited encoding");
1085 if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)) {
1086 /* not us, so add the previous realm to transited set */
1087 if (num_realms < 0 || num_realms + 1 > UINT_MAX/sizeof(*realms)) {
1091 tmp = realloc(realms, (num_realms + 1) * sizeof(*realms));
1097 realms[num_realms] = strdup(tgt_realm);
1098 if(realms[num_realms] == NULL){
1104 if(num_realms == 0) {
1105 if(strcmp(client_realm, server_realm))
1106 kdc_log(0, "cross-realm %s -> %s", client_realm, server_realm);
1110 for(i = 0; i < num_realms; i++)
1111 l += strlen(realms[i]) + 2;
1115 for(i = 0; i < num_realms; i++) {
1117 strlcat(rs, ", ", l);
1118 strlcat(rs, realms[i], l);
1120 kdc_log(0, "cross-realm %s -> %s via [%s]", client_realm, server_realm, rs);
1125 ret = krb5_check_transited(context, client_realm,
1127 realms, num_realms, NULL);
1129 krb5_warn(context, ret, "cross-realm %s -> %s",
1130 client_realm, server_realm);
1133 et->flags.transited_policy_checked = 1;
1135 et->transited.tr_type = DOMAIN_X500_COMPRESS;
1136 ret = krb5_domain_x500_encode(realms, num_realms, &et->transited.contents);
1138 krb5_warn(context, ret, "Encoding transited encoding");
1140 for(i = 0; i < num_realms; i++)
1147 static krb5_error_code
1148 tgs_make_reply(KDC_REQ_BODY *b,
1150 EncTicketPart *adtkt,
1151 AuthorizationData *auth_data,
1154 krb5_principal client_principal,
1156 krb5_enctype cetype,
1157 const char **e_text,
1163 KDCOptions f = b->kdc_options;
1164 krb5_error_code ret;
1167 EncryptionKey *ekey;
1173 for(i = 0; i < b->etype.len; i++){
1174 ret = krb5_enctype_to_keytype(context, b->etype.val[i], &kt);
1177 if(adtkt->key.keytype == kt)
1180 if(i == b->etype.len)
1181 return KRB5KDC_ERR_ETYPE_NOSUPP;
1182 etype = b->etype.val[i];
1184 ret = find_keys(NULL, server, NULL, NULL, &skey, &etype,
1185 b->etype.val, b->etype.len);
1187 kdc_log(0, "Server has no support for etypes");
1193 memset(&rep, 0, sizeof(rep));
1194 memset(&et, 0, sizeof(et));
1195 memset(&ek, 0, sizeof(ek));
1198 rep.msg_type = krb_tgs_rep;
1200 et.authtime = tgt->authtime;
1202 et.endtime = min(tgt->endtime, *b->till);
1203 ALLOC(et.starttime);
1204 *et.starttime = kdc_time;
1206 ret = check_tgs_flags(b, tgt, &et);
1210 /* We should check the transited encoding if:
1211 1) the request doesn't ask not to be checked
1212 2) globally enforcing a check
1213 3) principal requires checking
1214 4) we allow non-check per-principal, but principal isn't marked as allowing this
1215 5) we don't globally allow this
1218 #define GLOBAL_FORCE_TRANSITED_CHECK (trpolicy == TRPOLICY_ALWAYS_CHECK)
1219 #define GLOBAL_ALLOW_PER_PRINCIPAL (trpolicy == TRPOLICY_ALLOW_PER_PRINCIPAL)
1220 #define GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK (trpolicy == TRPOLICY_ALWAYS_HONOUR_REQUEST)
1221 /* these will consult the database in future release */
1222 #define PRINCIPAL_FORCE_TRANSITED_CHECK(P) 0
1223 #define PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(P) 0
1225 ret = fix_transited_encoding(!f.disable_transited_check ||
1226 GLOBAL_FORCE_TRANSITED_CHECK ||
1227 PRINCIPAL_FORCE_TRANSITED_CHECK(server) ||
1228 !((GLOBAL_ALLOW_PER_PRINCIPAL &&
1229 PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(server)) ||
1230 GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK),
1231 &tgt->transited, &et,
1232 *krb5_princ_realm(context, client_principal),
1233 *krb5_princ_realm(context, server->principal),
1234 *krb5_princ_realm(context, krbtgt->principal));
1238 copy_Realm(krb5_princ_realm(context, server->principal),
1240 krb5_principal2principalname(&rep.ticket.sname, server->principal);
1241 copy_Realm(&tgt->crealm, &rep.crealm);
1242 if (f.request_anonymous)
1243 make_anonymous_principalname (&tgt->cname);
1245 copy_PrincipalName(&tgt->cname, &rep.cname);
1246 rep.ticket.tkt_vno = 5;
1248 ek.caddr = et.caddr;
1249 if(et.caddr == NULL)
1250 et.caddr = tgt->caddr;
1254 life = et.endtime - *et.starttime;
1255 if(client && client->max_life)
1256 life = min(life, *client->max_life);
1257 if(server->max_life)
1258 life = min(life, *server->max_life);
1259 et.endtime = *et.starttime + life;
1261 if(f.renewable_ok && tgt->flags.renewable &&
1262 et.renew_till == NULL && et.endtime < *b->till){
1263 et.flags.renewable = 1;
1264 ALLOC(et.renew_till);
1265 *et.renew_till = *b->till;
1269 renew = *et.renew_till - et.authtime;
1270 if(client && client->max_renew)
1271 renew = min(renew, *client->max_renew);
1272 if(server->max_renew)
1273 renew = min(renew, *server->max_renew);
1274 *et.renew_till = et.authtime + renew;
1278 *et.renew_till = min(*et.renew_till, *tgt->renew_till);
1279 *et.starttime = min(*et.starttime, *et.renew_till);
1280 et.endtime = min(et.endtime, *et.renew_till);
1283 *et.starttime = min(*et.starttime, et.endtime);
1285 if(*et.starttime == et.endtime){
1286 ret = KRB5KDC_ERR_NEVER_VALID;
1289 if(et.renew_till && et.endtime == *et.renew_till){
1290 free(et.renew_till);
1291 et.renew_till = NULL;
1292 et.flags.renewable = 0;
1295 et.flags.pre_authent = tgt->flags.pre_authent;
1296 et.flags.hw_authent = tgt->flags.hw_authent;
1297 et.flags.anonymous = tgt->flags.anonymous;
1299 /* XXX Check enc-authorization-data */
1300 et.authorization_data = auth_data;
1302 krb5_generate_random_keyblock(context, etype, &et.key);
1303 et.crealm = tgt->crealm;
1304 et.cname = tgt->cname;
1307 /* MIT must have at least one last_req */
1308 ek.last_req.len = 1;
1309 ek.last_req.val = calloc(1, sizeof(*ek.last_req.val));
1310 ek.nonce = b->nonce;
1311 ek.flags = et.flags;
1312 ek.authtime = et.authtime;
1313 ek.starttime = et.starttime;
1314 ek.endtime = et.endtime;
1315 ek.renew_till = et.renew_till;
1316 ek.srealm = rep.ticket.realm;
1317 ek.sname = rep.ticket.sname;
1319 /* It is somewhat unclear where the etype in the following
1320 encryption should come from. What we have is a session
1321 key in the passed tgt, and a list of preferred etypes
1322 *for the new ticket*. Should we pick the best possible
1323 etype, given the keytype in the tgt, or should we look
1324 at the etype list here as well? What if the tgt
1325 session key is DES3 and we want a ticket with a (say)
1326 CAST session key. Should the DES3 etype be added to the
1327 etype list, even if we don't want a session key with
1329 ret = encode_reply(&rep, &et, &ek, etype, adtkt ? 0 : server->kvno, ekey,
1330 0, &tgt->key, e_text, reply);
1333 free_TransitedEncoding(&et.transited);
1337 free(et.renew_till);
1338 free_LastReq(&ek.last_req);
1339 memset(et.key.keyvalue.data, 0, et.key.keyvalue.length);
1340 free_EncryptionKey(&et.key);
1344 static krb5_error_code
1345 tgs_check_authenticator(krb5_auth_context ac,
1347 const char **e_text,
1350 krb5_authenticator auth;
1354 krb5_error_code ret;
1357 krb5_auth_con_getauthenticator(context, ac, &auth);
1358 if(auth->cksum == NULL){
1359 kdc_log(0, "No authenticator in request");
1360 ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
1364 * according to RFC1510 it doesn't need to be keyed,
1365 * but according to the latest draft it needs to.
1369 !krb5_checksum_is_keyed(context, auth->cksum->cksumtype)
1372 !krb5_checksum_is_collision_proof(context, auth->cksum->cksumtype)) {
1373 kdc_log(0, "Bad checksum type in authenticator: %d",
1374 auth->cksum->cksumtype);
1375 ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
1379 /* XXX should not re-encode this */
1380 ASN1_MALLOC_ENCODE(KDC_REQ_BODY, buf, buf_size, b, &len, ret);
1382 kdc_log(0, "Failed to encode KDC-REQ-BODY: %s",
1383 krb5_get_err_text(context, ret));
1386 if(buf_size != len) {
1388 kdc_log(0, "Internal error in ASN.1 encoder");
1389 *e_text = "KDC internal error";
1390 ret = KRB5KRB_ERR_GENERIC;
1393 ret = krb5_crypto_init(context, key, 0, &crypto);
1396 kdc_log(0, "krb5_crypto_init failed: %s",
1397 krb5_get_err_text(context, ret));
1400 ret = krb5_verify_checksum(context,
1402 KRB5_KU_TGS_REQ_AUTH_CKSUM,
1407 krb5_crypto_destroy(context, crypto);
1409 kdc_log(0, "Failed to verify checksum: %s",
1410 krb5_get_err_text(context, ret));
1413 free_Authenticator(auth);
1419 * return the realm of a krbtgt-ticket or NULL
1423 get_krbtgt_realm(const PrincipalName *p)
1425 if(p->name_string.len == 2
1426 && strcmp(p->name_string.val[0], KRB5_TGS_NAME) == 0)
1427 return p->name_string.val[1];
1433 find_rpath(Realm crealm, Realm srealm)
1435 const char *new_realm = krb5_config_get_string(context,
1441 return (Realm)new_realm;
1446 need_referral(krb5_principal server, krb5_realm **realms)
1448 if(server->name.name_type != KRB5_NT_SRV_INST ||
1449 server->name.name_string.len != 2)
1452 return krb5_get_host_realm_int(context, server->name.name_string.val[1],
1453 FALSE, realms) == 0;
1456 static krb5_error_code
1457 tgs_rep2(KDC_REQ_BODY *b,
1461 const struct sockaddr *from_addr,
1466 krb5_error_code ret;
1467 krb5_principal princ;
1468 krb5_auth_context ac = NULL;
1469 krb5_ticket *ticket = NULL;
1470 krb5_flags ap_req_options;
1471 krb5_flags verify_ap_req_flags;
1472 const char *e_text = NULL;
1475 hdb_entry *krbtgt = NULL;
1478 krb5_enctype cetype;
1479 krb5_principal cp = NULL;
1480 krb5_principal sp = NULL;
1481 AuthorizationData *auth_data = NULL;
1486 memset(&ap_req, 0, sizeof(ap_req));
1487 ret = krb5_decode_ap_req(context, &tgs_req->padata_value, &ap_req);
1489 kdc_log(0, "Failed to decode AP-REQ: %s",
1490 krb5_get_err_text(context, ret));
1494 if(!get_krbtgt_realm(&ap_req.ticket.sname)){
1495 /* XXX check for ticket.sname == req.sname */
1496 kdc_log(0, "PA-DATA is not a ticket-granting ticket");
1497 ret = KRB5KDC_ERR_POLICY; /* ? */
1501 principalname2krb5_principal(&princ,
1502 ap_req.ticket.sname,
1503 ap_req.ticket.realm);
1505 ret = db_fetch(princ, &krbtgt);
1509 krb5_unparse_name(context, princ, &p);
1510 krb5_free_principal(context, princ);
1511 kdc_log(0, "Ticket-granting ticket not found in database: %s: %s",
1512 p, krb5_get_err_text(context, ret));
1514 ret = KRB5KRB_AP_ERR_NOT_US;
1518 if(ap_req.ticket.enc_part.kvno &&
1519 *ap_req.ticket.enc_part.kvno != krbtgt->kvno){
1522 krb5_unparse_name (context, princ, &p);
1523 krb5_free_principal(context, princ);
1524 kdc_log(0, "Ticket kvno = %d, DB kvno = %d (%s)",
1525 *ap_req.ticket.enc_part.kvno,
1529 ret = KRB5KRB_AP_ERR_BADKEYVER;
1533 ret = hdb_enctype2key(context, krbtgt, ap_req.ticket.enc_part.etype, &tkey);
1536 krb5_enctype_to_string(context, ap_req.ticket.enc_part.etype, &str);
1537 kdc_log(0, "No server key found for %s", str);
1539 ret = KRB5KRB_AP_ERR_BADKEYVER;
1543 if (b->kdc_options.validate)
1544 verify_ap_req_flags = KRB5_VERIFY_AP_REQ_IGNORE_INVALID;
1546 verify_ap_req_flags = 0;
1548 ret = krb5_verify_ap_req2(context,
1553 verify_ap_req_flags,
1556 KRB5_KU_TGS_REQ_AUTH);
1558 krb5_free_principal(context, princ);
1560 kdc_log(0, "Failed to verify AP-REQ: %s",
1561 krb5_get_err_text(context, ret));
1566 krb5_authenticator auth;
1568 ret = krb5_auth_con_getauthenticator(context, ac, &auth);
1570 *csec = malloc(sizeof(**csec));
1571 if (*csec == NULL) {
1572 krb5_free_authenticator(context, &auth);
1573 kdc_log(0, "malloc failed");
1576 **csec = auth->ctime;
1577 *cusec = malloc(sizeof(**cusec));
1578 if (*cusec == NULL) {
1579 krb5_free_authenticator(context, &auth);
1580 kdc_log(0, "malloc failed");
1583 **csec = auth->cusec;
1584 krb5_free_authenticator(context, &auth);
1588 cetype = ap_req.authenticator.etype;
1590 tgt = &ticket->ticket;
1592 ret = tgs_check_authenticator(ac, b, &e_text, &tgt->key);
1594 if (b->enc_authorization_data) {
1595 krb5_keyblock *subkey;
1597 ret = krb5_auth_con_getremotesubkey(context,
1601 krb5_auth_con_free(context, ac);
1602 kdc_log(0, "Failed to get remote subkey: %s",
1603 krb5_get_err_text(context, ret));
1607 ret = krb5_auth_con_getkey(context, ac, &subkey);
1609 krb5_auth_con_free(context, ac);
1610 kdc_log(0, "Failed to get session key: %s",
1611 krb5_get_err_text(context, ret));
1616 krb5_auth_con_free(context, ac);
1617 kdc_log(0, "Failed to get key for enc-authorization-data");
1618 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
1621 ret = krb5_crypto_init(context, subkey, 0, &crypto);
1623 krb5_auth_con_free(context, ac);
1624 kdc_log(0, "krb5_crypto_init failed: %s",
1625 krb5_get_err_text(context, ret));
1628 ret = krb5_decrypt_EncryptedData (context,
1630 KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
1631 b->enc_authorization_data,
1633 krb5_crypto_destroy(context, crypto);
1635 krb5_auth_con_free(context, ac);
1636 kdc_log(0, "Failed to decrypt enc-authorization-data");
1637 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
1640 krb5_free_keyblock(context, subkey);
1642 ret = decode_AuthorizationData(ad.data, ad.length, auth_data, NULL);
1644 krb5_auth_con_free(context, ac);
1647 kdc_log(0, "Failed to decode authorization data");
1648 ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
1653 krb5_auth_con_free(context, ac);
1656 kdc_log(0, "Failed to verify authenticator: %s",
1657 krb5_get_err_text(context, ret));
1664 char *spn = NULL, *cpn = NULL;
1665 hdb_entry *server = NULL, *client = NULL;
1667 EncTicketPart adtkt;
1672 if(b->kdc_options.enc_tkt_in_skey){
1678 if(b->additional_tickets == NULL ||
1679 b->additional_tickets->len == 0){
1680 ret = KRB5KDC_ERR_BADOPTION; /* ? */
1681 kdc_log(0, "No second ticket present in request");
1684 t = &b->additional_tickets->val[0];
1685 if(!get_krbtgt_realm(&t->sname)){
1686 kdc_log(0, "Additional ticket is not a ticket-granting ticket");
1687 ret = KRB5KDC_ERR_POLICY;
1690 principalname2krb5_principal(&p, t->sname, t->realm);
1691 ret = db_fetch(p, &uu);
1692 krb5_free_principal(context, p);
1694 if (ret == HDB_ERR_NOENTRY)
1695 ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
1698 ret = hdb_enctype2key(context, uu, t->enc_part.etype, &tkey);
1700 ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
1703 ret = krb5_decrypt_ticket(context, t, &tkey->key, &adtkt, 0);
1711 principalname2krb5_principal(&sp, *s, r);
1712 krb5_unparse_name(context, sp, &spn);
1713 principalname2krb5_principal(&cp, tgt->cname, tgt->crealm);
1714 krb5_unparse_name(context, cp, &cpn);
1715 unparse_flags (KDCOptions2int(b->kdc_options), KDCOptions_units,
1716 opt_str, sizeof(opt_str));
1718 kdc_log(0, "TGS-REQ %s from %s for %s [%s]",
1719 cpn, from, spn, opt_str);
1721 kdc_log(0, "TGS-REQ %s from %s for %s", cpn, from, spn);
1723 ret = db_fetch(sp, &server);
1726 Realm req_rlm, new_rlm;
1729 if ((req_rlm = get_krbtgt_realm(&sp->name)) != NULL) {
1731 new_rlm = find_rpath(tgt->crealm, req_rlm);
1733 kdc_log(5, "krbtgt for realm %s not found, trying %s",
1735 krb5_free_principal(context, sp);
1737 krb5_make_principal(context, &sp, r,
1738 KRB5_TGS_NAME, new_rlm, NULL);
1739 krb5_unparse_name(context, sp, &spn);
1743 } else if(need_referral(sp, &realms)) {
1744 if (strcmp(realms[0], sp->realm) != 0) {
1745 kdc_log(5, "returning a referral to realm %s for "
1746 "server %s that was not found",
1748 krb5_free_principal(context, sp);
1750 krb5_make_principal(context, &sp, r, KRB5_TGS_NAME,
1752 krb5_unparse_name(context, sp, &spn);
1753 krb5_free_host_realm(context, realms);
1756 krb5_free_host_realm(context, realms);
1758 kdc_log(0, "Server not found in database: %s: %s", spn,
1759 krb5_get_err_text(context, ret));
1760 if (ret == HDB_ERR_NOENTRY)
1761 ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
1765 ret = db_fetch(cp, &client);
1767 kdc_log(1, "Client not found in database: %s: %s",
1768 cpn, krb5_get_err_text(context, ret));
1770 /* XXX check client only if same realm as krbtgt-instance */
1772 kdc_log(0, "Client not found in database: %s: %s",
1773 cpn, krb5_get_err_text(context, ret));
1774 if (ret == HDB_ERR_NOENTRY)
1775 ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
1780 if(strcmp(krb5_principal_get_realm(context, sp),
1781 krb5_principal_get_comp_string(context, krbtgt->principal, 1)) != 0) {
1783 ret = krb5_unparse_name(context, krbtgt->principal, &tpn);
1784 kdc_log(0, "Request with wrong krbtgt: %s", (ret == 0) ? tpn : "<unknown>");
1787 ret = KRB5KRB_AP_ERR_NOT_US;
1792 ret = check_flags(client, cpn, server, spn, FALSE);
1796 if((b->kdc_options.validate || b->kdc_options.renew) &&
1797 !krb5_principal_compare(context,
1799 server->principal)){
1800 kdc_log(0, "Inconsistent request.");
1801 ret = KRB5KDC_ERR_SERVER_NOMATCH;
1805 /* check for valid set of addresses */
1806 if(!check_addresses(tgt->caddr, from_addr)) {
1807 ret = KRB5KRB_AP_ERR_BADADDR;
1808 kdc_log(0, "Request from wrong address");
1812 ret = tgs_make_reply(b,
1814 b->kdc_options.enc_tkt_in_skey ? &adtkt : NULL,
1835 krb5_mk_error(context,
1849 krb5_free_principal(context, cp);
1850 krb5_free_principal(context, sp);
1852 krb5_free_ticket(context, ticket);
1855 free_AP_REQ(&ap_req);
1857 free_AuthorizationData(auth_data);
1869 tgs_rep(KDC_REQ *req,
1872 struct sockaddr *from_addr)
1874 krb5_error_code ret;
1876 PA_DATA *tgs_req = NULL;
1877 time_t *csec = NULL;
1880 if(req->padata == NULL){
1881 ret = KRB5KDC_ERR_PREAUTH_REQUIRED; /* XXX ??? */
1882 kdc_log(0, "TGS-REQ from %s without PA-DATA", from);
1886 tgs_req = find_padata(req, &i, KRB5_PADATA_TGS_REQ);
1888 if(tgs_req == NULL){
1889 ret = KRB5KDC_ERR_PADATA_TYPE_NOSUPP;
1891 kdc_log(0, "TGS-REQ from %s without PA-TGS-REQ", from);
1894 ret = tgs_rep2(&req->req_body, tgs_req, data, from, from_addr,
1897 if(ret && data->data == NULL){
1898 krb5_mk_error(context,