2 * Copyright (c) 1997 - 2005 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
34 #include "krb5_locl.h"
35 __RCSID("$Heimdal: v4_glue.c 22071 2007-11-14 20:04:50Z lha $"
38 #include "krb5-v4compat.h"
44 #define RCHECK(r,func,label) \
45 do { (r) = func ; if (r) goto label; } while(0);
48 /* include this here, to avoid dependencies on libkrb */
50 static const int _tkt_lifetimes
[TKTLIFENUMFIXED
] = {
51 38400, 41055, 43894, 46929, 50174, 53643, 57352, 61318,
52 65558, 70091, 74937, 80119, 85658, 91581, 97914, 104684,
53 111922, 119661, 127935, 136781, 146239, 156350, 167161, 178720,
54 191077, 204289, 218415, 233517, 249664, 266926, 285383, 305116,
55 326213, 348769, 372885, 398668, 426234, 455705, 487215, 520904,
56 556921, 595430, 636601, 680618, 727680, 777995, 831789, 889303,
57 950794, 1016537, 1086825, 1161973, 1242318, 1328218, 1420057, 1518247,
58 1623226, 1735464, 1855462, 1983758, 2120925, 2267576, 2424367, 2592000
62 _krb5_krb_time_to_life(time_t start
, time_t end
)
65 time_t life
= end
- start
;
67 if (life
> MAXTKTLIFETIME
|| life
<= 0)
70 if (krb_no_long_lifetimes
)
71 return (life
+ 5*60 - 1)/(5*60);
75 return TKTLIFENOEXPIRE
;
76 if (life
< _tkt_lifetimes
[0])
77 return (life
+ 5*60 - 1)/(5*60);
78 for (i
=0; i
<TKTLIFENUMFIXED
; i
++)
79 if (life
<= _tkt_lifetimes
[i
])
80 return i
+ TKTLIFEMINFIXED
;
85 time_t KRB5_LIB_FUNCTION
86 _krb5_krb_life_to_time(int start
, int life_
)
88 unsigned char life
= (unsigned char) life_
;
91 if (krb_no_long_lifetimes
)
92 return start
+ life
*5*60;
95 if (life
== TKTLIFENOEXPIRE
)
97 if (life
< TKTLIFEMINFIXED
)
98 return start
+ life
*5*60;
99 if (life
> TKTLIFEMAXFIXED
)
100 return start
+ MAXTKTLIFETIME
;
101 return start
+ _tkt_lifetimes
[life
- TKTLIFEMINFIXED
];
105 * Get the name of the krb4 credentials cache, will use `tkfile' as
106 * the name if that is passed in. `cc' must be free()ed by caller,
109 static krb5_error_code
110 get_krb4_cc_name(const char *tkfile
, char **cc
)
117 path
= getenv("KRBTKFILE");
122 if (asprintf(cc
, "%s%u", TKT_ROOT
, (unsigned)getuid()) < 0)
125 *cc
= strdup(tkfile
);
133 * Write a Kerberos 4 ticket file
136 #define KRB5_TF_LCK_RETRY_COUNT 50
137 #define KRB5_TF_LCK_RETRY 1
139 static krb5_error_code
140 write_v4_cc(krb5_context context
, const char *tkfile
,
141 krb5_storage
*sp
, int append
)
149 ret
= get_krb4_cc_name(tkfile
, &path
);
151 krb5_set_error_string(context
,
152 "krb5_krb_tf_setup: failed getting "
153 "the krb4 credentials cache name");
157 fd
= open(path
, O_WRONLY
|O_CREAT
, 0600);
160 krb5_set_error_string(context
,
161 "krb5_krb_tf_setup: error opening file %s",
167 if (fstat(fd
, &sb
) != 0 || !S_ISREG(sb
.st_mode
)) {
168 krb5_set_error_string(context
,
169 "krb5_krb_tf_setup: tktfile %s is not a file",
173 return KRB5_FCC_PERM
;
176 for (i
= 0; i
< KRB5_TF_LCK_RETRY_COUNT
; i
++) {
177 if (flock(fd
, LOCK_EX
| LOCK_NB
) < 0) {
178 sleep(KRB5_TF_LCK_RETRY
);
182 if (i
== KRB5_TF_LCK_RETRY_COUNT
) {
183 krb5_set_error_string(context
,
184 "krb5_krb_tf_setup: failed to lock %s",
188 return KRB5_FCC_PERM
;
192 ret
= ftruncate(fd
, 0);
195 krb5_set_error_string(context
,
196 "krb5_krb_tf_setup: failed to truncate %s",
200 return KRB5_FCC_PERM
;
203 ret
= lseek(fd
, 0L, SEEK_END
);
212 krb5_storage_to_data(sp
, &data
);
214 ret
= write(fd
, data
.data
, data
.length
);
215 if (ret
!= data
.length
)
218 krb5_free_data_contents(context
, &data
);
231 krb5_error_code KRB5_LIB_FUNCTION
232 _krb5_krb_tf_setup(krb5_context context
,
233 struct credentials
*v4creds
,
240 sp
= krb5_storage_emem();
244 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_HOST
);
245 krb5_storage_set_eof_code(sp
, KRB5_CC_IO
);
247 krb5_clear_error_string(context
);
250 RCHECK(ret
, krb5_store_stringz(sp
, v4creds
->pname
), error
);
251 RCHECK(ret
, krb5_store_stringz(sp
, v4creds
->pinst
), error
);
255 RCHECK(ret
, krb5_store_stringz(sp
, v4creds
->service
), error
);
256 RCHECK(ret
, krb5_store_stringz(sp
, v4creds
->instance
), error
);
257 RCHECK(ret
, krb5_store_stringz(sp
, v4creds
->realm
), error
);
258 ret
= krb5_storage_write(sp
, v4creds
->session
, 8);
263 RCHECK(ret
, krb5_store_int32(sp
, v4creds
->lifetime
), error
);
264 RCHECK(ret
, krb5_store_int32(sp
, v4creds
->kvno
), error
);
265 RCHECK(ret
, krb5_store_int32(sp
, v4creds
->ticket_st
.length
), error
);
267 ret
= krb5_storage_write(sp
, v4creds
->ticket_st
.dat
,
268 v4creds
->ticket_st
.length
);
269 if (ret
!= v4creds
->ticket_st
.length
) {
273 RCHECK(ret
, krb5_store_int32(sp
, v4creds
->issue_date
), error
);
275 ret
= write_v4_cc(context
, tkfile
, sp
, append
);
278 krb5_storage_free(sp
);
287 krb5_error_code KRB5_LIB_FUNCTION
288 _krb5_krb_dest_tkt(krb5_context context
, const char *tkfile
)
293 ret
= get_krb4_cc_name(tkfile
, &path
);
295 krb5_set_error_string(context
,
296 "krb5_krb_tf_setup: failed getting "
297 "the krb4 credentials cache name");
301 if (unlink(path
) < 0) {
303 krb5_set_error_string(context
,
304 "krb5_krb_dest_tkt failed removing the cache "
305 "with error %s", strerror(ret
));
316 static krb5_error_code
317 decrypt_etext(krb5_context context
, const krb5_keyblock
*key
,
318 const krb5_data
*cdata
, krb5_data
*data
)
323 ret
= krb5_crypto_init(context
, key
, ETYPE_DES_PCBC_NONE
, &crypto
);
327 ret
= krb5_decrypt(context
, crypto
, 0, cdata
->data
, cdata
->length
, data
);
328 krb5_crypto_destroy(context
, crypto
);
338 static const char eightzeros
[8] = "\x00\x00\x00\x00\x00\x00\x00\x00";
340 static krb5_error_code
341 storage_to_etext(krb5_context context
,
343 const krb5_keyblock
*key
,
351 /* multiple of eight bytes */
353 size
= krb5_storage_seek(sp
, 0, SEEK_END
);
355 return KRB4ET_RD_AP_UNDEC
;
356 size
= 8 - (size
& 7);
358 ret
= krb5_storage_write(sp
, eightzeros
, size
);
360 return KRB4ET_RD_AP_UNDEC
;
362 ret
= krb5_storage_to_data(sp
, &data
);
366 ret
= krb5_crypto_init(context
, key
, ETYPE_DES_PCBC_NONE
, &crypto
);
368 krb5_data_free(&data
);
372 ret
= krb5_encrypt(context
, crypto
, 0, data
.data
, data
.length
, enc_data
);
374 krb5_data_free(&data
);
375 krb5_crypto_destroy(context
, crypto
);
384 static krb5_error_code
385 put_nir(krb5_storage
*sp
, const char *name
,
386 const char *instance
, const char *realm
)
390 RCHECK(ret
, krb5_store_stringz(sp
, name
), error
);
391 RCHECK(ret
, krb5_store_stringz(sp
, instance
), error
);
393 RCHECK(ret
, krb5_store_stringz(sp
, realm
), error
);
403 krb5_error_code KRB5_LIB_FUNCTION
404 _krb5_krb_create_ticket(krb5_context context
,
407 const char *pinstance
,
410 const krb5_keyblock
*session
,
414 const char *sinstance
,
415 const krb5_keyblock
*key
,
421 krb5_data_zero(enc_data
);
423 sp
= krb5_storage_emem();
425 krb5_set_error_string(context
, "malloc: out of memory");
428 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_BE
);
430 RCHECK(ret
, krb5_store_int8(sp
, flags
), error
);
431 RCHECK(ret
, put_nir(sp
, pname
, pinstance
, prealm
), error
);
432 RCHECK(ret
, krb5_store_int32(sp
, ntohl(paddress
)), error
);
435 ret
= krb5_storage_write(sp
,
436 session
->keyvalue
.data
,
437 session
->keyvalue
.length
);
438 if (ret
!= session
->keyvalue
.length
) {
439 ret
= KRB4ET_INTK_PROT
;
443 RCHECK(ret
, krb5_store_int8(sp
, life
), error
);
444 RCHECK(ret
, krb5_store_int32(sp
, life_sec
), error
);
445 RCHECK(ret
, put_nir(sp
, sname
, sinstance
, NULL
), error
);
447 ret
= storage_to_etext(context
, sp
, key
, enc_data
);
450 krb5_storage_free(sp
);
452 krb5_set_error_string(context
, "Failed to encode kerberos 4 ticket");
461 krb5_error_code KRB5_LIB_FUNCTION
462 _krb5_krb_create_ciph(krb5_context context
,
463 const krb5_keyblock
*session
,
465 const char *instance
,
469 const krb5_data
*ticket
,
471 const krb5_keyblock
*key
,
477 krb5_data_zero(enc_data
);
479 sp
= krb5_storage_emem();
481 krb5_set_error_string(context
, "malloc: out of memory");
484 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_BE
);
487 ret
= krb5_storage_write(sp
,
488 session
->keyvalue
.data
,
489 session
->keyvalue
.length
);
490 if (ret
!= session
->keyvalue
.length
) {
491 ret
= KRB4ET_INTK_PROT
;
495 RCHECK(ret
, put_nir(sp
, service
, instance
, realm
), error
);
496 RCHECK(ret
, krb5_store_int8(sp
, life
), error
);
497 RCHECK(ret
, krb5_store_int8(sp
, kvno
), error
);
498 RCHECK(ret
, krb5_store_int8(sp
, ticket
->length
), error
);
499 ret
= krb5_storage_write(sp
, ticket
->data
, ticket
->length
);
500 if (ret
!= ticket
->length
) {
501 ret
= KRB4ET_INTK_PROT
;
504 RCHECK(ret
, krb5_store_int32(sp
, kdc_time
), error
);
506 ret
= storage_to_etext(context
, sp
, key
, enc_data
);
509 krb5_storage_free(sp
);
511 krb5_set_error_string(context
, "Failed to encode kerberos 4 ticket");
520 krb5_error_code KRB5_LIB_FUNCTION
521 _krb5_krb_create_auth_reply(krb5_context context
,
529 const krb5_data
*cipher
,
535 krb5_data_zero(data
);
537 sp
= krb5_storage_emem();
539 krb5_set_error_string(context
, "malloc: out of memory");
542 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_BE
);
544 RCHECK(ret
, krb5_store_int8(sp
, KRB_PROT_VERSION
), error
);
545 RCHECK(ret
, krb5_store_int8(sp
, AUTH_MSG_KDC_REPLY
), error
);
546 RCHECK(ret
, put_nir(sp
, pname
, pinst
, prealm
), error
);
547 RCHECK(ret
, krb5_store_int32(sp
, time_ws
), error
);
548 RCHECK(ret
, krb5_store_int8(sp
, n
), error
);
549 RCHECK(ret
, krb5_store_int32(sp
, x_date
), error
);
550 RCHECK(ret
, krb5_store_int8(sp
, kvno
), error
);
551 RCHECK(ret
, krb5_store_int16(sp
, cipher
->length
), error
);
552 ret
= krb5_storage_write(sp
, cipher
->data
, cipher
->length
);
553 if (ret
!= cipher
->length
) {
554 ret
= KRB4ET_INTK_PROT
;
558 ret
= krb5_storage_to_data(sp
, data
);
561 krb5_storage_free(sp
);
563 krb5_set_error_string(context
, "Failed to encode kerberos 4 ticket");
572 krb5_error_code KRB5_LIB_FUNCTION
573 _krb5_krb_cr_err_reply(krb5_context context
,
579 const char *e_string
,
585 krb5_data_zero(data
);
587 if (name
== NULL
) name
= "";
588 if (inst
== NULL
) inst
= "";
589 if (realm
== NULL
) realm
= "";
590 if (e_string
== NULL
) e_string
= "";
592 sp
= krb5_storage_emem();
594 krb5_set_error_string(context
, "malloc: out of memory");
597 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_BE
);
599 RCHECK(ret
, krb5_store_int8(sp
, KRB_PROT_VERSION
), error
);
600 RCHECK(ret
, krb5_store_int8(sp
, AUTH_MSG_ERR_REPLY
), error
);
601 RCHECK(ret
, put_nir(sp
, name
, inst
, realm
), error
);
602 RCHECK(ret
, krb5_store_int32(sp
, time_ws
), error
);
603 /* If it is a Kerberos 4 error-code, remove the et BASE */
604 if (e
>= ERROR_TABLE_BASE_krb
&& e
<= ERROR_TABLE_BASE_krb
+ 255)
605 e
-= ERROR_TABLE_BASE_krb
;
606 RCHECK(ret
, krb5_store_int32(sp
, e
), error
);
607 RCHECK(ret
, krb5_store_stringz(sp
, e_string
), error
);
609 ret
= krb5_storage_to_data(sp
, data
);
612 krb5_storage_free(sp
);
614 krb5_set_error_string(context
, "Failed to encode kerberos 4 error");
619 static krb5_error_code
620 get_v4_stringz(krb5_storage
*sp
, char **str
, size_t max_len
)
624 ret
= krb5_ret_stringz(sp
, str
);
627 if (strlen(*str
) > max_len
) {
630 return KRB4ET_INTK_PROT
;
639 krb5_error_code KRB5_LIB_FUNCTION
640 _krb5_krb_decomp_ticket(krb5_context context
,
641 const krb5_data
*enc_ticket
,
642 const krb5_keyblock
*key
,
643 const char *local_realm
,
646 struct _krb5_krb_auth_data
*ad
)
650 krb5_storage
*sp
= NULL
;
652 unsigned char des_key
[8];
654 memset(ad
, 0, sizeof(*ad
));
655 krb5_data_zero(&ticket
);
660 RCHECK(ret
, decrypt_etext(context
, key
, enc_ticket
, &ticket
), error
);
662 sp
= krb5_storage_from_data(&ticket
);
664 krb5_data_free(&ticket
);
665 krb5_set_error_string(context
, "alloc: out of memory");
669 krb5_storage_set_eof_code(sp
, KRB4ET_INTK_PROT
);
671 RCHECK(ret
, krb5_ret_int8(sp
, &ad
->k_flags
), error
);
672 RCHECK(ret
, get_v4_stringz(sp
, &ad
->pname
, ANAME_SZ
), error
);
673 RCHECK(ret
, get_v4_stringz(sp
, &ad
->pinst
, INST_SZ
), error
);
674 RCHECK(ret
, get_v4_stringz(sp
, &ad
->prealm
, REALM_SZ
), error
);
675 RCHECK(ret
, krb5_ret_uint32(sp
, &ad
->address
), error
);
677 size
= krb5_storage_read(sp
, des_key
, sizeof(des_key
));
678 if (size
!= sizeof(des_key
)) {
679 ret
= KRB4ET_INTK_PROT
;
683 RCHECK(ret
, krb5_ret_uint8(sp
, &ad
->life
), error
);
686 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_LE
);
688 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_BE
);
690 RCHECK(ret
, krb5_ret_uint32(sp
, &ad
->time_sec
), error
);
692 RCHECK(ret
, get_v4_stringz(sp
, sname
, ANAME_SZ
), error
);
693 RCHECK(ret
, get_v4_stringz(sp
, sinstance
, INST_SZ
), error
);
695 ret
= krb5_keyblock_init(context
, ETYPE_DES_PCBC_NONE
,
696 des_key
, sizeof(des_key
), &ad
->session
);
700 if (strlen(ad
->prealm
) == 0) {
702 ad
->prealm
= strdup(local_realm
);
703 if (ad
->prealm
== NULL
) {
710 memset(des_key
, 0, sizeof(des_key
));
712 krb5_storage_free(sp
);
713 krb5_data_free(&ticket
);
723 _krb5_krb_free_auth_data(context
, ad
);
724 krb5_set_error_string(context
, "Failed to decode v4 ticket");
733 krb5_error_code KRB5_LIB_FUNCTION
734 _krb5_krb_rd_req(krb5_context context
,
737 const char *instance
,
738 const char *local_realm
,
740 const krb5_keyblock
*key
,
741 struct _krb5_krb_auth_data
*ad
)
745 krb5_data ticket
, eaut
, aut
;
751 uint8_t ticket_length
;
756 char *sinstance
= NULL
;
757 char *r_realm
= NULL
;
759 char *r_instance
= NULL
;
761 uint32_t r_time_sec
; /* Coarse time from authenticator */
762 unsigned long delta_t
; /* Time in authenticator - local time */
763 long tkt_age
; /* Age of ticket */
767 krb5_data_zero(&ticket
);
768 krb5_data_zero(&eaut
);
769 krb5_data_zero(&aut
);
771 sp
= krb5_storage_from_data(authent
);
773 krb5_set_error_string(context
, "alloc: out of memory");
777 krb5_storage_set_eof_code(sp
, KRB4ET_INTK_PROT
);
779 ret
= krb5_ret_int8(sp
, &pvno
);
781 krb5_set_error_string(context
, "Failed reading v4 pvno");
785 if (pvno
!= KRB_PROT_VERSION
) {
786 ret
= KRB4ET_RD_AP_VERSION
;
787 krb5_set_error_string(context
, "Failed v4 pvno not 4");
791 ret
= krb5_ret_int8(sp
, &type
);
793 krb5_set_error_string(context
, "Failed readin v4 type");
797 little_endian
= type
& 1;
800 if(type
!= AUTH_MSG_APPL_REQUEST
&& type
!= AUTH_MSG_APPL_REQUEST_MUTUAL
) {
801 ret
= KRB4ET_RD_AP_MSG_TYPE
;
802 krb5_set_error_string(context
, "Not a valid v4 request type");
806 RCHECK(ret
, krb5_ret_int8(sp
, &s_kvno
), error
);
807 RCHECK(ret
, get_v4_stringz(sp
, &realm
, REALM_SZ
), error
);
808 RCHECK(ret
, krb5_ret_uint8(sp
, &ticket_length
), error
);
809 RCHECK(ret
, krb5_ret_uint8(sp
, &eaut_length
), error
);
810 RCHECK(ret
, krb5_data_alloc(&ticket
, ticket_length
), error
);
812 size
= krb5_storage_read(sp
, ticket
.data
, ticket
.length
);
813 if (size
!= ticket
.length
) {
814 ret
= KRB4ET_INTK_PROT
;
815 krb5_set_error_string(context
, "Failed reading v4 ticket");
819 /* Decrypt and take apart ticket */
820 ret
= _krb5_krb_decomp_ticket(context
, &ticket
, key
, local_realm
,
821 &sname
, &sinstance
, ad
);
825 RCHECK(ret
, krb5_data_alloc(&eaut
, eaut_length
), error
);
827 size
= krb5_storage_read(sp
, eaut
.data
, eaut
.length
);
828 if (size
!= eaut
.length
) {
829 ret
= KRB4ET_INTK_PROT
;
830 krb5_set_error_string(context
, "Failed reading v4 authenticator");
834 krb5_storage_free(sp
);
837 ret
= decrypt_etext(context
, &ad
->session
, &eaut
, &aut
);
841 sp
= krb5_storage_from_data(&aut
);
844 krb5_set_error_string(context
, "alloc: out of memory");
849 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_LE
);
851 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_BE
);
853 RCHECK(ret
, get_v4_stringz(sp
, &r_name
, ANAME_SZ
), error
);
854 RCHECK(ret
, get_v4_stringz(sp
, &r_instance
, INST_SZ
), error
);
855 RCHECK(ret
, get_v4_stringz(sp
, &r_realm
, REALM_SZ
), error
);
857 RCHECK(ret
, krb5_ret_uint32(sp
, &ad
->checksum
), error
);
858 RCHECK(ret
, krb5_ret_uint8(sp
, &time_5ms
), error
);
859 RCHECK(ret
, krb5_ret_uint32(sp
, &r_time_sec
), error
);
861 if (strcmp(ad
->pname
, r_name
) != 0 ||
862 strcmp(ad
->pinst
, r_instance
) != 0 ||
863 strcmp(ad
->prealm
, r_realm
) != 0) {
864 krb5_set_error_string(context
, "v4 principal mismatch");
865 ret
= KRB4ET_RD_AP_INCON
;
869 if (from_addr
&& ad
->address
&& from_addr
!= ad
->address
) {
870 krb5_set_error_string(context
, "v4 bad address in ticket");
871 ret
= KRB4ET_RD_AP_BADD
;
875 gettimeofday(&tv
, NULL
);
876 delta_t
= abs((int)(tv
.tv_sec
- r_time_sec
));
877 if (delta_t
> CLOCK_SKEW
) {
878 ret
= KRB4ET_RD_AP_TIME
;
879 krb5_set_error_string(context
, "v4 clock skew");
883 /* Now check for expiration of ticket */
885 tkt_age
= tv
.tv_sec
- ad
->time_sec
;
887 if ((tkt_age
< 0) && (-tkt_age
> CLOCK_SKEW
)) {
888 ret
= KRB4ET_RD_AP_NYV
;
889 krb5_set_error_string(context
, "v4 clock skew for expiration");
893 if (tv
.tv_sec
> _krb5_krb_life_to_time(ad
->time_sec
, ad
->life
)) {
894 ret
= KRB4ET_RD_AP_EXP
;
895 krb5_set_error_string(context
, "v4 ticket expired");
901 krb5_data_free(&ticket
);
902 krb5_data_free(&eaut
);
903 krb5_data_free(&aut
);
917 krb5_storage_free(sp
);
920 krb5_clear_error_string(context
);
929 void KRB5_LIB_FUNCTION
930 _krb5_krb_free_auth_data(krb5_context context
, struct _krb5_krb_auth_data
*ad
)
938 krb5_free_keyblock_contents(context
, &ad
->session
);
939 memset(ad
, 0, sizeof(*ad
));