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.4 2004/08/13 19:28:26 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
< n
; i
++)
335 if (pa
.val
[i
].etype
== etypes
[j
])
337 for(i
= 0; i
< client
->keys
.len
; i
++) {
338 if(client
->keys
.val
[i
].key
.keytype
== etypes
[j
])
339 if((ret
= make_etype_info_entry(&pa
.val
[n
++],
340 &client
->keys
.val
[i
])) != 0) {
341 free_ETYPE_INFO(&pa
);
347 for(i
= 0; i
< client
->keys
.len
; i
++) {
348 for(j
= 0; j
< etypes_len
; j
++) {
349 if(client
->keys
.val
[i
].key
.keytype
== etypes
[j
])
352 if((ret
= make_etype_info_entry(&pa
.val
[n
++],
353 &client
->keys
.val
[i
])) != 0) {
354 free_ETYPE_INFO(&pa
);
362 krb5_unparse_name(context
, client
->principal
, &name
);
363 kdc_log(0, "internal error in get_pa_etype_info(%s): %d != %d",
369 ASN1_MALLOC_ENCODE(ETYPE_INFO
, buf
, len
, &pa
, &len
, ret
);
370 free_ETYPE_INFO(&pa
);
373 ret
= realloc_method_data(md
);
378 md
->val
[md
->len
- 1].padata_type
= KRB5_PADATA_ETYPE_INFO
;
379 md
->val
[md
->len
- 1].padata_value
.length
= len
;
380 md
->val
[md
->len
- 1].padata_value
.data
= buf
;
385 * verify the flags on `client' and `server', returning 0
386 * if they are OK and generating an error messages and returning
387 * and error code otherwise.
391 check_flags(hdb_entry
*client
, const char *client_name
,
392 hdb_entry
*server
, const char *server_name
,
393 krb5_boolean is_as_req
)
397 if (client
->flags
.invalid
) {
398 kdc_log(0, "Client (%s) has invalid bit set", client_name
);
399 return KRB5KDC_ERR_POLICY
;
402 if(!client
->flags
.client
){
403 kdc_log(0, "Principal may not act as client -- %s",
405 return KRB5KDC_ERR_POLICY
;
408 if (client
->valid_start
&& *client
->valid_start
> kdc_time
) {
409 kdc_log(0, "Client not yet valid -- %s", client_name
);
410 return KRB5KDC_ERR_CLIENT_NOTYET
;
413 if (client
->valid_end
&& *client
->valid_end
< kdc_time
) {
414 kdc_log(0, "Client expired -- %s", client_name
);
415 return KRB5KDC_ERR_NAME_EXP
;
418 if (client
->pw_end
&& *client
->pw_end
< kdc_time
419 && !server
->flags
.change_pw
) {
420 kdc_log(0, "Client's key has expired -- %s", client_name
);
421 return KRB5KDC_ERR_KEY_EXPIRED
;
427 if (server
!= NULL
) {
428 if (server
->flags
.invalid
) {
429 kdc_log(0, "Server has invalid flag set -- %s", server_name
);
430 return KRB5KDC_ERR_POLICY
;
433 if(!server
->flags
.server
){
434 kdc_log(0, "Principal may not act as server -- %s",
436 return KRB5KDC_ERR_POLICY
;
439 if(!is_as_req
&& server
->flags
.initial
) {
440 kdc_log(0, "AS-REQ is required for server -- %s", server_name
);
441 return KRB5KDC_ERR_POLICY
;
444 if (server
->valid_start
&& *server
->valid_start
> kdc_time
) {
445 kdc_log(0, "Server not yet valid -- %s", server_name
);
446 return KRB5KDC_ERR_SERVICE_NOTYET
;
449 if (server
->valid_end
&& *server
->valid_end
< kdc_time
) {
450 kdc_log(0, "Server expired -- %s", server_name
);
451 return KRB5KDC_ERR_SERVICE_EXP
;
454 if (server
->pw_end
&& *server
->pw_end
< kdc_time
) {
455 kdc_log(0, "Server's key has expired -- %s", server_name
);
456 return KRB5KDC_ERR_KEY_EXPIRED
;
463 * Return TRUE if `from' is part of `addresses' taking into consideration
464 * the configuration variables that tells us how strict we should be about
469 check_addresses(HostAddresses
*addresses
, const struct sockaddr
*from
)
475 if(check_ticket_addresses
== 0)
478 if(addresses
== NULL
)
479 return allow_null_ticket_addresses
;
481 ret
= krb5_sockaddr2address (context
, from
, &addr
);
485 result
= krb5_address_search(context
, &addr
, addresses
);
486 krb5_free_address (context
, &addr
);
494 struct sockaddr
*from_addr
)
496 KDC_REQ_BODY
*b
= &req
->req_body
;
498 KDCOptions f
= b
->kdc_options
;
499 hdb_entry
*client
= NULL
, *server
= NULL
;
500 krb5_enctype cetype
, setype
;
503 krb5_principal client_princ
= NULL
, server_princ
= NULL
;
504 char *client_name
= NULL
, *server_name
= NULL
;
505 krb5_error_code ret
= 0;
506 const char *e_text
= NULL
;
510 memset(&rep
, 0, sizeof(rep
));
512 if(b
->sname
== NULL
){
513 ret
= KRB5KRB_ERR_GENERIC
;
514 e_text
= "No server in request";
516 principalname2krb5_principal (&server_princ
, *(b
->sname
), b
->realm
);
517 krb5_unparse_name(context
, server_princ
, &server_name
);
520 kdc_log(0, "AS-REQ malformed server name from %s", from
);
524 if(b
->cname
== NULL
){
525 ret
= KRB5KRB_ERR_GENERIC
;
526 e_text
= "No client in request";
528 principalname2krb5_principal (&client_princ
, *(b
->cname
), b
->realm
);
529 krb5_unparse_name(context
, client_princ
, &client_name
);
532 kdc_log(0, "AS-REQ malformed client name from %s", from
);
536 kdc_log(0, "AS-REQ %s from %s for %s", client_name
, from
, server_name
);
538 ret
= db_fetch(client_princ
, &client
);
540 kdc_log(0, "UNKNOWN -- %s: %s", client_name
,
541 krb5_get_err_text(context
, ret
));
542 ret
= KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN
;
546 ret
= db_fetch(server_princ
, &server
);
548 kdc_log(0, "UNKNOWN -- %s: %s", server_name
,
549 krb5_get_err_text(context
, ret
));
550 ret
= KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
;
554 ret
= check_flags(client
, client_name
, server
, server_name
, TRUE
);
558 memset(&et
, 0, sizeof(et
));
559 memset(&ek
, 0, sizeof(ek
));
565 kdc_log(5, "Looking for pa-data -- %s", client_name
);
566 while((pa
= find_padata(req
, &i
, KRB5_PADATA_ENC_TIMESTAMP
))){
571 EncryptedData enc_data
;
576 ret
= decode_EncryptedData(pa
->padata_value
.data
,
577 pa
->padata_value
.length
,
581 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
582 kdc_log(5, "Failed to decode PA-DATA -- %s",
587 ret
= hdb_enctype2key(context
, client
, enc_data
.etype
, &pa_key
);
590 e_text
= "No key matches pa-data";
591 ret
= KRB5KDC_ERR_PREAUTH_FAILED
;
592 if(krb5_enctype_to_string(context
, enc_data
.etype
, &estr
))
595 kdc_log(5, "No client key matching pa-data (%d) -- %s",
596 enc_data
.etype
, client_name
);
598 kdc_log(5, "No client key matching pa-data (%s) -- %s",
602 free_EncryptedData(&enc_data
);
607 ret
= krb5_crypto_init(context
, &pa_key
->key
, 0, &crypto
);
609 kdc_log(0, "krb5_crypto_init failed: %s",
610 krb5_get_err_text(context
, ret
));
611 free_EncryptedData(&enc_data
);
615 ret
= krb5_decrypt_EncryptedData (context
,
617 KRB5_KU_PA_ENC_TIMESTAMP
,
620 krb5_crypto_destroy(context
, crypto
);
622 if(hdb_next_enctype2key(context
, client
,
623 enc_data
.etype
, &pa_key
) == 0)
625 free_EncryptedData(&enc_data
);
626 e_text
= "Failed to decrypt PA-DATA";
627 kdc_log (5, "Failed to decrypt PA-DATA -- %s",
629 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
632 free_EncryptedData(&enc_data
);
633 ret
= decode_PA_ENC_TS_ENC(ts_data
.data
,
637 krb5_data_free(&ts_data
);
639 e_text
= "Failed to decode PA-ENC-TS-ENC";
640 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
641 kdc_log (5, "Failed to decode PA-ENC-TS_ENC -- %s",
645 patime
= p
.patimestamp
;
646 free_PA_ENC_TS_ENC(&p
);
647 if (abs(kdc_time
- p
.patimestamp
) > context
->max_skew
) {
648 ret
= KRB5KDC_ERR_PREAUTH_FAILED
;
649 e_text
= "Too large time skew";
650 kdc_log(0, "Too large time skew -- %s", client_name
);
653 et
.flags
.pre_authent
= 1;
654 kdc_log(2, "Pre-authentication succeded -- %s", client_name
);
657 if(found_pa
== 0 && require_preauth
)
659 /* We come here if we found a pa-enc-timestamp, but if there
660 was some problem with it, other than too large skew */
661 if(found_pa
&& et
.flags
.pre_authent
== 0){
662 kdc_log(0, "%s -- %s", e_text
, client_name
);
666 }else if (require_preauth
667 || client
->flags
.require_preauth
668 || server
->flags
.require_preauth
) {
669 METHOD_DATA method_data
;
677 method_data
.val
= NULL
;
679 ret
= realloc_method_data(&method_data
);
680 pa
= &method_data
.val
[method_data
.len
-1];
681 pa
->padata_type
= KRB5_PADATA_ENC_TIMESTAMP
;
682 pa
->padata_value
.length
= 0;
683 pa
->padata_value
.data
= NULL
;
685 ret
= get_pa_etype_info(&method_data
, client
,
686 b
->etype
.val
, b
->etype
.len
); /* XXX check ret */
688 ASN1_MALLOC_ENCODE(METHOD_DATA
, buf
, len
, &method_data
, &len
, ret
);
689 free_METHOD_DATA(&method_data
);
691 foo_data
.length
= len
;
693 ret
= KRB5KDC_ERR_PREAUTH_REQUIRED
;
694 krb5_mk_error(context
,
696 "Need to use PA-ENC-TIMESTAMP",
704 kdc_log(0, "No PA-ENC-TIMESTAMP -- %s", client_name
);
709 ret
= find_keys(client
, server
, &ckey
, &cetype
, &skey
, &setype
,
710 b
->etype
.val
, b
->etype
.len
);
712 kdc_log(0, "Server/client has no support for etypes");
720 ret
= krb5_enctype_to_string(context
, cetype
, &cet
);
722 ret
= krb5_enctype_to_string(context
, setype
, &set
);
724 kdc_log(5, "Using %s/%s", cet
, set
);
730 kdc_log(5, "Using e-types %d/%d", cetype
, setype
);
735 unparse_flags(KDCOptions2int(f
), KDCOptions_units
, str
, sizeof(str
));
737 kdc_log(2, "Requested flags: %s", str
);
741 if(f
.renew
|| f
.validate
|| f
.proxy
|| f
.forwarded
|| f
.enc_tkt_in_skey
742 || (f
.request_anonymous
&& !allow_anonymous
)) {
743 ret
= KRB5KDC_ERR_BADOPTION
;
744 kdc_log(0, "Bad KDC options -- %s", client_name
);
749 rep
.msg_type
= krb_as_rep
;
750 copy_Realm(&b
->realm
, &rep
.crealm
);
751 if (f
.request_anonymous
)
752 make_anonymous_principalname (&rep
.cname
);
754 copy_PrincipalName(b
->cname
, &rep
.cname
);
755 rep
.ticket
.tkt_vno
= 5;
756 copy_Realm(&b
->realm
, &rep
.ticket
.realm
);
757 copy_PrincipalName(b
->sname
, &rep
.ticket
.sname
);
759 et
.flags
.initial
= 1;
760 if(client
->flags
.forwardable
&& server
->flags
.forwardable
)
761 et
.flags
.forwardable
= f
.forwardable
;
762 else if (f
.forwardable
) {
763 ret
= KRB5KDC_ERR_POLICY
;
764 kdc_log(0, "Ticket may not be forwardable -- %s", client_name
);
767 if(client
->flags
.proxiable
&& server
->flags
.proxiable
)
768 et
.flags
.proxiable
= f
.proxiable
;
769 else if (f
.proxiable
) {
770 ret
= KRB5KDC_ERR_POLICY
;
771 kdc_log(0, "Ticket may not be proxiable -- %s", client_name
);
774 if(client
->flags
.postdate
&& server
->flags
.postdate
)
775 et
.flags
.may_postdate
= f
.allow_postdate
;
776 else if (f
.allow_postdate
){
777 ret
= KRB5KDC_ERR_POLICY
;
778 kdc_log(0, "Ticket may not be postdatable -- %s", client_name
);
782 /* check for valid set of addresses */
783 if(!check_addresses(b
->addresses
, from_addr
)) {
784 ret
= KRB5KRB_AP_ERR_BADADDR
;
785 kdc_log(0, "Bad address list requested -- %s", client_name
);
789 krb5_generate_random_keyblock(context
, setype
, &et
.key
);
790 copy_PrincipalName(&rep
.cname
, &et
.cname
);
791 copy_Realm(&b
->realm
, &et
.crealm
);
797 start
= et
.authtime
= kdc_time
;
799 if(f
.postdated
&& req
->req_body
.from
){
801 start
= *et
.starttime
= *req
->req_body
.from
;
802 et
.flags
.invalid
= 1;
803 et
.flags
.postdated
= 1; /* XXX ??? */
808 /* be careful not overflowing */
811 t
= start
+ min(t
- start
, *client
->max_life
);
813 t
= start
+ min(t
- start
, *server
->max_life
);
815 t
= min(t
, start
+ realm
->max_life
);
818 if(f
.renewable_ok
&& et
.endtime
< *b
->till
){
820 if(b
->rtime
== NULL
){
824 if(*b
->rtime
< *b
->till
)
825 *b
->rtime
= *b
->till
;
827 if(f
.renewable
&& b
->rtime
){
831 if(client
->max_renew
)
832 t
= start
+ min(t
- start
, *client
->max_renew
);
833 if(server
->max_renew
)
834 t
= start
+ min(t
- start
, *server
->max_renew
);
836 t
= min(t
, start
+ realm
->max_renew
);
838 ALLOC(et
.renew_till
);
840 et
.flags
.renewable
= 1;
844 if (f
.request_anonymous
)
845 et
.flags
.anonymous
= 1;
849 copy_HostAddresses(b
->addresses
, et
.caddr
);
852 et
.transited
.tr_type
= DOMAIN_X500_COMPRESS
;
853 krb5_data_zero(&et
.transited
.contents
);
855 copy_EncryptionKey(&et
.key
, &ek
.key
);
857 /* The MIT ASN.1 library (obviously) doesn't tell lengths encoded
858 * as 0 and as 0x80 (meaning indefinite length) apart, and is thus
859 * incapable of correctly decoding SEQUENCE OF's of zero length.
861 * To fix this, always send at least one no-op last_req
863 * If there's a pw_end or valid_end we will use that,
864 * otherwise just a dummy lr.
866 ek
.last_req
.val
= malloc(2 * sizeof(*ek
.last_req
.val
));
869 && (kdc_warn_pwexpire
== 0
870 || kdc_time
+ kdc_warn_pwexpire
<= *client
->pw_end
)) {
871 ek
.last_req
.val
[ek
.last_req
.len
].lr_type
= LR_PW_EXPTIME
;
872 ek
.last_req
.val
[ek
.last_req
.len
].lr_value
= *client
->pw_end
;
875 if (client
->valid_end
) {
876 ek
.last_req
.val
[ek
.last_req
.len
].lr_type
= LR_ACCT_EXPTIME
;
877 ek
.last_req
.val
[ek
.last_req
.len
].lr_value
= *client
->valid_end
;
880 if (ek
.last_req
.len
== 0) {
881 ek
.last_req
.val
[ek
.last_req
.len
].lr_type
= LR_NONE
;
882 ek
.last_req
.val
[ek
.last_req
.len
].lr_value
= 0;
886 if (client
->valid_end
|| client
->pw_end
) {
887 ALLOC(ek
.key_expiration
);
888 if (client
->valid_end
) {
890 *ek
.key_expiration
= min(*client
->valid_end
, *client
->pw_end
);
892 *ek
.key_expiration
= *client
->valid_end
;
894 *ek
.key_expiration
= *client
->pw_end
;
896 ek
.key_expiration
= NULL
;
898 ek
.authtime
= et
.authtime
;
901 *ek
.starttime
= *et
.starttime
;
903 ek
.endtime
= et
.endtime
;
905 ALLOC(ek
.renew_till
);
906 *ek
.renew_till
= *et
.renew_till
;
908 copy_Realm(&rep
.ticket
.realm
, &ek
.srealm
);
909 copy_PrincipalName(&rep
.ticket
.sname
, &ek
.sname
);
912 copy_HostAddresses(et
.caddr
, ek
.caddr
);
915 set_salt_padata (&rep
.padata
, ckey
->salt
);
916 ret
= encode_reply(&rep
, &et
, &ek
, setype
, server
->kvno
, &skey
->key
,
917 client
->kvno
, &ckey
->key
, &e_text
, reply
);
918 free_EncTicketPart(&et
);
919 free_EncKDCRepPart(&ek
);
923 krb5_mk_error(context
,
936 krb5_free_principal(context
, client_princ
);
939 krb5_free_principal(context
, server_princ
);
949 static krb5_error_code
950 check_tgs_flags(KDC_REQ_BODY
*b
, EncTicketPart
*tgt
, EncTicketPart
*et
)
952 KDCOptions f
= b
->kdc_options
;
955 if(!tgt
->flags
.invalid
|| tgt
->starttime
== NULL
){
956 kdc_log(0, "Bad request to validate ticket");
957 return KRB5KDC_ERR_BADOPTION
;
959 if(*tgt
->starttime
> kdc_time
){
960 kdc_log(0, "Early request to validate ticket");
961 return KRB5KRB_AP_ERR_TKT_NYV
;
964 et
->flags
.invalid
= 0;
965 }else if(tgt
->flags
.invalid
){
966 kdc_log(0, "Ticket-granting ticket has INVALID flag set");
967 return KRB5KRB_AP_ERR_TKT_INVALID
;
971 if(!tgt
->flags
.forwardable
){
972 kdc_log(0, "Bad request for forwardable ticket");
973 return KRB5KDC_ERR_BADOPTION
;
975 et
->flags
.forwardable
= 1;
978 if(!tgt
->flags
.forwardable
){
979 kdc_log(0, "Request to forward non-forwardable ticket");
980 return KRB5KDC_ERR_BADOPTION
;
982 et
->flags
.forwarded
= 1;
983 et
->caddr
= b
->addresses
;
985 if(tgt
->flags
.forwarded
)
986 et
->flags
.forwarded
= 1;
989 if(!tgt
->flags
.proxiable
){
990 kdc_log(0, "Bad request for proxiable ticket");
991 return KRB5KDC_ERR_BADOPTION
;
993 et
->flags
.proxiable
= 1;
996 if(!tgt
->flags
.proxiable
){
997 kdc_log(0, "Request to proxy non-proxiable ticket");
998 return KRB5KDC_ERR_BADOPTION
;
1000 et
->flags
.proxy
= 1;
1001 et
->caddr
= b
->addresses
;
1003 if(tgt
->flags
.proxy
)
1004 et
->flags
.proxy
= 1;
1006 if(f
.allow_postdate
){
1007 if(!tgt
->flags
.may_postdate
){
1008 kdc_log(0, "Bad request for post-datable ticket");
1009 return KRB5KDC_ERR_BADOPTION
;
1011 et
->flags
.may_postdate
= 1;
1014 if(!tgt
->flags
.may_postdate
){
1015 kdc_log(0, "Bad request for postdated ticket");
1016 return KRB5KDC_ERR_BADOPTION
;
1019 *et
->starttime
= *b
->from
;
1020 et
->flags
.postdated
= 1;
1021 et
->flags
.invalid
= 1;
1022 }else if(b
->from
&& *b
->from
> kdc_time
+ context
->max_skew
){
1023 kdc_log(0, "Ticket cannot be postdated");
1024 return KRB5KDC_ERR_CANNOT_POSTDATE
;
1028 if(!tgt
->flags
.renewable
){
1029 kdc_log(0, "Bad request for renewable ticket");
1030 return KRB5KDC_ERR_BADOPTION
;
1032 et
->flags
.renewable
= 1;
1033 ALLOC(et
->renew_till
);
1034 fix_time(&b
->rtime
);
1035 *et
->renew_till
= *b
->rtime
;
1039 if(!tgt
->flags
.renewable
|| tgt
->renew_till
== NULL
){
1040 kdc_log(0, "Request to renew non-renewable ticket");
1041 return KRB5KDC_ERR_BADOPTION
;
1043 old_life
= tgt
->endtime
;
1045 old_life
-= *tgt
->starttime
;
1047 old_life
-= tgt
->authtime
;
1048 et
->endtime
= *et
->starttime
+ old_life
;
1049 if (et
->renew_till
!= NULL
)
1050 et
->endtime
= min(*et
->renew_till
, et
->endtime
);
1053 /* checks for excess flags */
1054 if(f
.request_anonymous
&& !allow_anonymous
){
1055 kdc_log(0, "Request for anonymous ticket");
1056 return KRB5KDC_ERR_BADOPTION
;
1061 static krb5_error_code
1062 fix_transited_encoding(krb5_boolean check_policy
,
1063 TransitedEncoding
*tr
,
1065 const char *client_realm
,
1066 const char *server_realm
,
1067 const char *tgt_realm
)
1069 krb5_error_code ret
= 0;
1070 char **realms
, **tmp
;
1074 if(tr
->tr_type
!= DOMAIN_X500_COMPRESS
) {
1075 kdc_log(0, "Unknown transited type: %u", tr
->tr_type
);
1076 return KRB5KDC_ERR_TRTYPE_NOSUPP
;
1079 ret
= krb5_domain_x500_decode(context
,
1086 krb5_warn(context
, ret
, "Decoding transited encoding");
1089 if(strcmp(client_realm
, tgt_realm
) && strcmp(server_realm
, tgt_realm
)) {
1090 /* not us, so add the previous realm to transited set */
1091 if (num_realms
< 0 || num_realms
+ 1 > UINT_MAX
/sizeof(*realms
)) {
1095 tmp
= realloc(realms
, (num_realms
+ 1) * sizeof(*realms
));
1101 realms
[num_realms
] = strdup(tgt_realm
);
1102 if(realms
[num_realms
] == NULL
){
1108 if(num_realms
== 0) {
1109 if(strcmp(client_realm
, server_realm
))
1110 kdc_log(0, "cross-realm %s -> %s", client_realm
, server_realm
);
1114 for(i
= 0; i
< num_realms
; i
++)
1115 l
+= strlen(realms
[i
]) + 2;
1119 for(i
= 0; i
< num_realms
; i
++) {
1121 strlcat(rs
, ", ", l
);
1122 strlcat(rs
, realms
[i
], l
);
1124 kdc_log(0, "cross-realm %s -> %s via [%s]", client_realm
, server_realm
, rs
);
1129 ret
= krb5_check_transited(context
, client_realm
,
1131 realms
, num_realms
, NULL
);
1133 krb5_warn(context
, ret
, "cross-realm %s -> %s",
1134 client_realm
, server_realm
);
1137 et
->flags
.transited_policy_checked
= 1;
1139 et
->transited
.tr_type
= DOMAIN_X500_COMPRESS
;
1140 ret
= krb5_domain_x500_encode(realms
, num_realms
, &et
->transited
.contents
);
1142 krb5_warn(context
, ret
, "Encoding transited encoding");
1144 for(i
= 0; i
< num_realms
; i
++)
1151 static krb5_error_code
1152 tgs_make_reply(KDC_REQ_BODY
*b
,
1154 EncTicketPart
*adtkt
,
1155 AuthorizationData
*auth_data
,
1158 krb5_principal client_principal
,
1160 krb5_enctype cetype
,
1161 const char **e_text
,
1167 KDCOptions f
= b
->kdc_options
;
1168 krb5_error_code ret
;
1171 EncryptionKey
*ekey
;
1177 for(i
= 0; i
< b
->etype
.len
; i
++){
1178 ret
= krb5_enctype_to_keytype(context
, b
->etype
.val
[i
], &kt
);
1181 if(adtkt
->key
.keytype
== kt
)
1184 if(i
== b
->etype
.len
)
1185 return KRB5KDC_ERR_ETYPE_NOSUPP
;
1186 etype
= b
->etype
.val
[i
];
1188 ret
= find_keys(NULL
, server
, NULL
, NULL
, &skey
, &etype
,
1189 b
->etype
.val
, b
->etype
.len
);
1191 kdc_log(0, "Server has no support for etypes");
1197 memset(&rep
, 0, sizeof(rep
));
1198 memset(&et
, 0, sizeof(et
));
1199 memset(&ek
, 0, sizeof(ek
));
1202 rep
.msg_type
= krb_tgs_rep
;
1204 et
.authtime
= tgt
->authtime
;
1206 et
.endtime
= min(tgt
->endtime
, *b
->till
);
1207 ALLOC(et
.starttime
);
1208 *et
.starttime
= kdc_time
;
1210 ret
= check_tgs_flags(b
, tgt
, &et
);
1214 /* We should check the transited encoding if:
1215 1) the request doesn't ask not to be checked
1216 2) globally enforcing a check
1217 3) principal requires checking
1218 4) we allow non-check per-principal, but principal isn't marked as allowing this
1219 5) we don't globally allow this
1222 #define GLOBAL_FORCE_TRANSITED_CHECK (trpolicy == TRPOLICY_ALWAYS_CHECK)
1223 #define GLOBAL_ALLOW_PER_PRINCIPAL (trpolicy == TRPOLICY_ALLOW_PER_PRINCIPAL)
1224 #define GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK (trpolicy == TRPOLICY_ALWAYS_HONOUR_REQUEST)
1225 /* these will consult the database in future release */
1226 #define PRINCIPAL_FORCE_TRANSITED_CHECK(P) 0
1227 #define PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(P) 0
1229 ret
= fix_transited_encoding(!f
.disable_transited_check
||
1230 GLOBAL_FORCE_TRANSITED_CHECK
||
1231 PRINCIPAL_FORCE_TRANSITED_CHECK(server
) ||
1232 !((GLOBAL_ALLOW_PER_PRINCIPAL
&&
1233 PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(server
)) ||
1234 GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK
),
1235 &tgt
->transited
, &et
,
1236 *krb5_princ_realm(context
, client_principal
),
1237 *krb5_princ_realm(context
, server
->principal
),
1238 *krb5_princ_realm(context
, krbtgt
->principal
));
1242 copy_Realm(krb5_princ_realm(context
, server
->principal
),
1244 krb5_principal2principalname(&rep
.ticket
.sname
, server
->principal
);
1245 copy_Realm(&tgt
->crealm
, &rep
.crealm
);
1246 if (f
.request_anonymous
)
1247 make_anonymous_principalname (&tgt
->cname
);
1249 copy_PrincipalName(&tgt
->cname
, &rep
.cname
);
1250 rep
.ticket
.tkt_vno
= 5;
1252 ek
.caddr
= et
.caddr
;
1253 if(et
.caddr
== NULL
)
1254 et
.caddr
= tgt
->caddr
;
1258 life
= et
.endtime
- *et
.starttime
;
1259 if(client
&& client
->max_life
)
1260 life
= min(life
, *client
->max_life
);
1261 if(server
->max_life
)
1262 life
= min(life
, *server
->max_life
);
1263 et
.endtime
= *et
.starttime
+ life
;
1265 if(f
.renewable_ok
&& tgt
->flags
.renewable
&&
1266 et
.renew_till
== NULL
&& et
.endtime
< *b
->till
){
1267 et
.flags
.renewable
= 1;
1268 ALLOC(et
.renew_till
);
1269 *et
.renew_till
= *b
->till
;
1273 renew
= *et
.renew_till
- et
.authtime
;
1274 if(client
&& client
->max_renew
)
1275 renew
= min(renew
, *client
->max_renew
);
1276 if(server
->max_renew
)
1277 renew
= min(renew
, *server
->max_renew
);
1278 *et
.renew_till
= et
.authtime
+ renew
;
1282 *et
.renew_till
= min(*et
.renew_till
, *tgt
->renew_till
);
1283 *et
.starttime
= min(*et
.starttime
, *et
.renew_till
);
1284 et
.endtime
= min(et
.endtime
, *et
.renew_till
);
1287 *et
.starttime
= min(*et
.starttime
, et
.endtime
);
1289 if(*et
.starttime
== et
.endtime
){
1290 ret
= KRB5KDC_ERR_NEVER_VALID
;
1293 if(et
.renew_till
&& et
.endtime
== *et
.renew_till
){
1294 free(et
.renew_till
);
1295 et
.renew_till
= NULL
;
1296 et
.flags
.renewable
= 0;
1299 et
.flags
.pre_authent
= tgt
->flags
.pre_authent
;
1300 et
.flags
.hw_authent
= tgt
->flags
.hw_authent
;
1301 et
.flags
.anonymous
= tgt
->flags
.anonymous
;
1303 /* XXX Check enc-authorization-data */
1304 et
.authorization_data
= auth_data
;
1306 krb5_generate_random_keyblock(context
, etype
, &et
.key
);
1307 et
.crealm
= tgt
->crealm
;
1308 et
.cname
= tgt
->cname
;
1311 /* MIT must have at least one last_req */
1312 ek
.last_req
.len
= 1;
1313 ek
.last_req
.val
= calloc(1, sizeof(*ek
.last_req
.val
));
1314 ek
.nonce
= b
->nonce
;
1315 ek
.flags
= et
.flags
;
1316 ek
.authtime
= et
.authtime
;
1317 ek
.starttime
= et
.starttime
;
1318 ek
.endtime
= et
.endtime
;
1319 ek
.renew_till
= et
.renew_till
;
1320 ek
.srealm
= rep
.ticket
.realm
;
1321 ek
.sname
= rep
.ticket
.sname
;
1323 /* It is somewhat unclear where the etype in the following
1324 encryption should come from. What we have is a session
1325 key in the passed tgt, and a list of preferred etypes
1326 *for the new ticket*. Should we pick the best possible
1327 etype, given the keytype in the tgt, or should we look
1328 at the etype list here as well? What if the tgt
1329 session key is DES3 and we want a ticket with a (say)
1330 CAST session key. Should the DES3 etype be added to the
1331 etype list, even if we don't want a session key with
1333 ret
= encode_reply(&rep
, &et
, &ek
, etype
, adtkt
? 0 : server
->kvno
, ekey
,
1334 0, &tgt
->key
, e_text
, reply
);
1337 free_TransitedEncoding(&et
.transited
);
1341 free(et
.renew_till
);
1342 free_LastReq(&ek
.last_req
);
1343 memset(et
.key
.keyvalue
.data
, 0, et
.key
.keyvalue
.length
);
1344 free_EncryptionKey(&et
.key
);
1348 static krb5_error_code
1349 tgs_check_authenticator(krb5_auth_context ac
,
1351 const char **e_text
,
1354 krb5_authenticator auth
;
1358 krb5_error_code ret
;
1361 krb5_auth_con_getauthenticator(context
, ac
, &auth
);
1362 if(auth
->cksum
== NULL
){
1363 kdc_log(0, "No authenticator in request");
1364 ret
= KRB5KRB_AP_ERR_INAPP_CKSUM
;
1368 * according to RFC1510 it doesn't need to be keyed,
1369 * but according to the latest draft it needs to.
1373 !krb5_checksum_is_keyed(context
, auth
->cksum
->cksumtype
)
1376 !krb5_checksum_is_collision_proof(context
, auth
->cksum
->cksumtype
)) {
1377 kdc_log(0, "Bad checksum type in authenticator: %d",
1378 auth
->cksum
->cksumtype
);
1379 ret
= KRB5KRB_AP_ERR_INAPP_CKSUM
;
1383 /* XXX should not re-encode this */
1384 ASN1_MALLOC_ENCODE(KDC_REQ_BODY
, buf
, buf_size
, b
, &len
, ret
);
1386 kdc_log(0, "Failed to encode KDC-REQ-BODY: %s",
1387 krb5_get_err_text(context
, ret
));
1390 if(buf_size
!= len
) {
1392 kdc_log(0, "Internal error in ASN.1 encoder");
1393 *e_text
= "KDC internal error";
1394 ret
= KRB5KRB_ERR_GENERIC
;
1397 ret
= krb5_crypto_init(context
, key
, 0, &crypto
);
1400 kdc_log(0, "krb5_crypto_init failed: %s",
1401 krb5_get_err_text(context
, ret
));
1404 ret
= krb5_verify_checksum(context
,
1406 KRB5_KU_TGS_REQ_AUTH_CKSUM
,
1411 krb5_crypto_destroy(context
, crypto
);
1413 kdc_log(0, "Failed to verify checksum: %s",
1414 krb5_get_err_text(context
, ret
));
1417 free_Authenticator(auth
);
1423 * return the realm of a krbtgt-ticket or NULL
1427 get_krbtgt_realm(const PrincipalName
*p
)
1429 if(p
->name_string
.len
== 2
1430 && strcmp(p
->name_string
.val
[0], KRB5_TGS_NAME
) == 0)
1431 return p
->name_string
.val
[1];
1437 find_rpath(Realm crealm
, Realm srealm
)
1439 const char *new_realm
= krb5_config_get_string(context
,
1445 return (Realm
)new_realm
;
1450 need_referral(krb5_principal server
, krb5_realm
**realms
)
1452 if(server
->name
.name_type
!= KRB5_NT_SRV_INST
||
1453 server
->name
.name_string
.len
!= 2)
1456 return krb5_get_host_realm_int(context
, server
->name
.name_string
.val
[1],
1457 FALSE
, realms
) == 0;
1460 static krb5_error_code
1461 tgs_rep2(KDC_REQ_BODY
*b
,
1465 const struct sockaddr
*from_addr
,
1470 krb5_error_code ret
;
1471 krb5_principal princ
;
1472 krb5_auth_context ac
= NULL
;
1473 krb5_ticket
*ticket
= NULL
;
1474 krb5_flags ap_req_options
;
1475 krb5_flags verify_ap_req_flags
;
1476 const char *e_text
= NULL
;
1479 hdb_entry
*krbtgt
= NULL
;
1482 krb5_enctype cetype
;
1483 krb5_principal cp
= NULL
;
1484 krb5_principal sp
= NULL
;
1485 AuthorizationData
*auth_data
= NULL
;
1490 memset(&ap_req
, 0, sizeof(ap_req
));
1491 ret
= krb5_decode_ap_req(context
, &tgs_req
->padata_value
, &ap_req
);
1493 kdc_log(0, "Failed to decode AP-REQ: %s",
1494 krb5_get_err_text(context
, ret
));
1498 if(!get_krbtgt_realm(&ap_req
.ticket
.sname
)){
1499 /* XXX check for ticket.sname == req.sname */
1500 kdc_log(0, "PA-DATA is not a ticket-granting ticket");
1501 ret
= KRB5KDC_ERR_POLICY
; /* ? */
1505 principalname2krb5_principal(&princ
,
1506 ap_req
.ticket
.sname
,
1507 ap_req
.ticket
.realm
);
1509 ret
= db_fetch(princ
, &krbtgt
);
1513 krb5_unparse_name(context
, princ
, &p
);
1514 krb5_free_principal(context
, princ
);
1515 kdc_log(0, "Ticket-granting ticket not found in database: %s: %s",
1516 p
, krb5_get_err_text(context
, ret
));
1518 ret
= KRB5KRB_AP_ERR_NOT_US
;
1522 if(ap_req
.ticket
.enc_part
.kvno
&&
1523 *ap_req
.ticket
.enc_part
.kvno
!= krbtgt
->kvno
){
1526 krb5_unparse_name (context
, princ
, &p
);
1527 krb5_free_principal(context
, princ
);
1528 kdc_log(0, "Ticket kvno = %d, DB kvno = %d (%s)",
1529 *ap_req
.ticket
.enc_part
.kvno
,
1533 ret
= KRB5KRB_AP_ERR_BADKEYVER
;
1537 ret
= hdb_enctype2key(context
, krbtgt
, ap_req
.ticket
.enc_part
.etype
, &tkey
);
1540 krb5_enctype_to_string(context
, ap_req
.ticket
.enc_part
.etype
, &str
);
1541 kdc_log(0, "No server key found for %s", str
);
1543 ret
= KRB5KRB_AP_ERR_BADKEYVER
;
1547 if (b
->kdc_options
.validate
)
1548 verify_ap_req_flags
= KRB5_VERIFY_AP_REQ_IGNORE_INVALID
;
1550 verify_ap_req_flags
= 0;
1552 ret
= krb5_verify_ap_req2(context
,
1557 verify_ap_req_flags
,
1560 KRB5_KU_TGS_REQ_AUTH
);
1562 krb5_free_principal(context
, princ
);
1564 kdc_log(0, "Failed to verify AP-REQ: %s",
1565 krb5_get_err_text(context
, ret
));
1570 krb5_authenticator auth
;
1572 ret
= krb5_auth_con_getauthenticator(context
, ac
, &auth
);
1574 *csec
= malloc(sizeof(**csec
));
1575 if (*csec
== NULL
) {
1576 krb5_free_authenticator(context
, &auth
);
1577 kdc_log(0, "malloc failed");
1580 **csec
= auth
->ctime
;
1581 *cusec
= malloc(sizeof(**cusec
));
1582 if (*cusec
== NULL
) {
1583 krb5_free_authenticator(context
, &auth
);
1584 kdc_log(0, "malloc failed");
1587 **csec
= auth
->cusec
;
1588 krb5_free_authenticator(context
, &auth
);
1592 cetype
= ap_req
.authenticator
.etype
;
1594 tgt
= &ticket
->ticket
;
1596 ret
= tgs_check_authenticator(ac
, b
, &e_text
, &tgt
->key
);
1598 if (b
->enc_authorization_data
) {
1599 krb5_keyblock
*subkey
;
1601 ret
= krb5_auth_con_getremotesubkey(context
,
1605 krb5_auth_con_free(context
, ac
);
1606 kdc_log(0, "Failed to get remote subkey: %s",
1607 krb5_get_err_text(context
, ret
));
1611 ret
= krb5_auth_con_getkey(context
, ac
, &subkey
);
1613 krb5_auth_con_free(context
, ac
);
1614 kdc_log(0, "Failed to get session key: %s",
1615 krb5_get_err_text(context
, ret
));
1620 krb5_auth_con_free(context
, ac
);
1621 kdc_log(0, "Failed to get key for enc-authorization-data");
1622 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
; /* ? */
1625 ret
= krb5_crypto_init(context
, subkey
, 0, &crypto
);
1627 krb5_auth_con_free(context
, ac
);
1628 kdc_log(0, "krb5_crypto_init failed: %s",
1629 krb5_get_err_text(context
, ret
));
1632 ret
= krb5_decrypt_EncryptedData (context
,
1634 KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY
,
1635 b
->enc_authorization_data
,
1637 krb5_crypto_destroy(context
, crypto
);
1639 krb5_auth_con_free(context
, ac
);
1640 kdc_log(0, "Failed to decrypt enc-authorization-data");
1641 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
; /* ? */
1644 krb5_free_keyblock(context
, subkey
);
1646 ret
= decode_AuthorizationData(ad
.data
, ad
.length
, auth_data
, NULL
);
1648 krb5_auth_con_free(context
, ac
);
1651 kdc_log(0, "Failed to decode authorization data");
1652 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
; /* ? */
1657 krb5_auth_con_free(context
, ac
);
1660 kdc_log(0, "Failed to verify authenticator: %s",
1661 krb5_get_err_text(context
, ret
));
1668 char *spn
= NULL
, *cpn
= NULL
;
1669 hdb_entry
*server
= NULL
, *client
= NULL
;
1671 EncTicketPart adtkt
;
1676 if(b
->kdc_options
.enc_tkt_in_skey
){
1682 if(b
->additional_tickets
== NULL
||
1683 b
->additional_tickets
->len
== 0){
1684 ret
= KRB5KDC_ERR_BADOPTION
; /* ? */
1685 kdc_log(0, "No second ticket present in request");
1688 t
= &b
->additional_tickets
->val
[0];
1689 if(!get_krbtgt_realm(&t
->sname
)){
1690 kdc_log(0, "Additional ticket is not a ticket-granting ticket");
1691 ret
= KRB5KDC_ERR_POLICY
;
1694 principalname2krb5_principal(&p
, t
->sname
, t
->realm
);
1695 ret
= db_fetch(p
, &uu
);
1696 krb5_free_principal(context
, p
);
1698 if (ret
== HDB_ERR_NOENTRY
)
1699 ret
= KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
;
1702 ret
= hdb_enctype2key(context
, uu
, t
->enc_part
.etype
, &tkey
);
1704 ret
= KRB5KDC_ERR_ETYPE_NOSUPP
; /* XXX */
1707 ret
= krb5_decrypt_ticket(context
, t
, &tkey
->key
, &adtkt
, 0);
1715 principalname2krb5_principal(&sp
, *s
, r
);
1716 krb5_unparse_name(context
, sp
, &spn
);
1717 principalname2krb5_principal(&cp
, tgt
->cname
, tgt
->crealm
);
1718 krb5_unparse_name(context
, cp
, &cpn
);
1719 unparse_flags (KDCOptions2int(b
->kdc_options
), KDCOptions_units
,
1720 opt_str
, sizeof(opt_str
));
1722 kdc_log(0, "TGS-REQ %s from %s for %s [%s]",
1723 cpn
, from
, spn
, opt_str
);
1725 kdc_log(0, "TGS-REQ %s from %s for %s", cpn
, from
, spn
);
1727 ret
= db_fetch(sp
, &server
);
1730 Realm req_rlm
, new_rlm
;
1733 if ((req_rlm
= get_krbtgt_realm(&sp
->name
)) != NULL
) {
1735 new_rlm
= find_rpath(tgt
->crealm
, req_rlm
);
1737 kdc_log(5, "krbtgt for realm %s not found, trying %s",
1739 krb5_free_principal(context
, sp
);
1741 krb5_make_principal(context
, &sp
, r
,
1742 KRB5_TGS_NAME
, new_rlm
, NULL
);
1743 krb5_unparse_name(context
, sp
, &spn
);
1747 } else if(need_referral(sp
, &realms
)) {
1748 if (strcmp(realms
[0], sp
->realm
) != 0) {
1749 kdc_log(5, "returning a referral to realm %s for "
1750 "server %s that was not found",
1752 krb5_free_principal(context
, sp
);
1754 krb5_make_principal(context
, &sp
, r
, KRB5_TGS_NAME
,
1756 krb5_unparse_name(context
, sp
, &spn
);
1757 krb5_free_host_realm(context
, realms
);
1760 krb5_free_host_realm(context
, realms
);
1762 kdc_log(0, "Server not found in database: %s: %s", spn
,
1763 krb5_get_err_text(context
, ret
));
1764 if (ret
== HDB_ERR_NOENTRY
)
1765 ret
= KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
;
1769 ret
= db_fetch(cp
, &client
);
1771 kdc_log(1, "Client not found in database: %s: %s",
1772 cpn
, krb5_get_err_text(context
, ret
));
1774 /* XXX check client only if same realm as krbtgt-instance */
1776 kdc_log(0, "Client not found in database: %s: %s",
1777 cpn
, krb5_get_err_text(context
, ret
));
1778 if (ret
== HDB_ERR_NOENTRY
)
1779 ret
= KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN
;
1784 if(strcmp(krb5_principal_get_realm(context
, sp
),
1785 krb5_principal_get_comp_string(context
, krbtgt
->principal
, 1)) != 0) {
1787 ret
= krb5_unparse_name(context
, krbtgt
->principal
, &tpn
);
1788 kdc_log(0, "Request with wrong krbtgt: %s", (ret
== 0) ? tpn
: "<unknown>");
1791 ret
= KRB5KRB_AP_ERR_NOT_US
;
1796 ret
= check_flags(client
, cpn
, server
, spn
, FALSE
);
1800 if((b
->kdc_options
.validate
|| b
->kdc_options
.renew
) &&
1801 !krb5_principal_compare(context
,
1803 server
->principal
)){
1804 kdc_log(0, "Inconsistent request.");
1805 ret
= KRB5KDC_ERR_SERVER_NOMATCH
;
1809 /* check for valid set of addresses */
1810 if(!check_addresses(tgt
->caddr
, from_addr
)) {
1811 ret
= KRB5KRB_AP_ERR_BADADDR
;
1812 kdc_log(0, "Request from wrong address");
1816 ret
= tgs_make_reply(b
,
1818 b
->kdc_options
.enc_tkt_in_skey
? &adtkt
: NULL
,
1839 krb5_mk_error(context
,
1853 krb5_free_principal(context
, cp
);
1854 krb5_free_principal(context
, sp
);
1856 krb5_free_ticket(context
, ticket
);
1859 free_AP_REQ(&ap_req
);
1861 free_AuthorizationData(auth_data
);
1873 tgs_rep(KDC_REQ
*req
,
1876 struct sockaddr
*from_addr
)
1878 krb5_error_code ret
;
1880 PA_DATA
*tgs_req
= NULL
;
1881 time_t *csec
= NULL
;
1884 if(req
->padata
== NULL
){
1885 ret
= KRB5KDC_ERR_PREAUTH_REQUIRED
; /* XXX ??? */
1886 kdc_log(0, "TGS-REQ from %s without PA-DATA", from
);
1890 tgs_req
= find_padata(req
, &i
, KRB5_PADATA_TGS_REQ
);
1892 if(tgs_req
== NULL
){
1893 ret
= KRB5KDC_ERR_PADATA_TYPE_NOSUPP
;
1895 kdc_log(0, "TGS-REQ from %s without PA-TGS-REQ", from
);
1898 ret
= tgs_rep2(&req
->req_body
, tgs_req
, data
, from
, from_addr
,
1901 if(ret
&& data
->data
== NULL
){
1902 krb5_mk_error(context
,