diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c index 1bc69ca..af66d2e 100644 --- a/src/lib/gssapi/krb5/init_sec_context.c +++ b/src/lib/gssapi/krb5/init_sec_context.c @@ -117,18 +117,18 @@ int krb5_gss_dbg_client_expcreds = 0; * Common code which fetches the correct krb5 credentials from the * ccache. */ -static krb5_error_code get_credentials(context, cred, server, now, +static krb5_error_code get_credentials(context, cred, server, endtime, out_creds) krb5_context context; krb5_gss_cred_id_t cred; krb5_gss_name_t server; - krb5_timestamp now; krb5_timestamp endtime; krb5_creds **out_creds; { krb5_error_code code; krb5_creds in_creds, evidence_creds, *result_creds = NULL; krb5_flags flags = 0; + krb5_timestamp now; *out_creds = NULL; @@ -209,8 +209,12 @@ static krb5_error_code get_credentials(context, cred, server, now, /* * Enforce a stricter limit (without timeskew forgiveness at the * boundaries) because accept_sec_context code is also similarly - * non-forgiving. + * non-forgiving. Re-read the time here to get the benefit of + * KDC time sync that would be reset to match the creds, in case + * we're using it. */ + if ((code = krb5_timeofday(context, &now))) + goto cleanup; if (!krb5_gss_dbg_client_expcreds && result_creds->times.endtime < now) { code = KRB5KRB_AP_ERR_TKT_EXPIRED; goto cleanup; @@ -580,7 +584,7 @@ kg_new_connection( &ctx->there))) goto cleanup; - code = get_credentials(context, cred, ctx->there, now, + code = get_credentials(context, cred, ctx->there, ctx->krb_times.endtime, &k_cred); if (code) goto cleanup; diff --git a/src/lib/krb5/ccache/cc_keyring.c b/src/lib/krb5/ccache/cc_keyring.c index a0c8035..35ed5ad 100644 --- a/src/lib/krb5/ccache/cc_keyring.c +++ b/src/lib/krb5/ccache/cc_keyring.c @@ -1134,7 +1134,6 @@ make_cache(key_serial_t collection_id, key_serial_t cache_id, static krb5_error_code KRB5_CALLCONV krb5_krcc_resolve(krb5_context context, krb5_ccache *id, const char *residual) { - krb5_os_context os_ctx = &context->os_context; krb5_error_code ret; key_serial_t collection_id, cache_id; char *anchor_name = NULL, *collection_name = NULL, *subsidiary_name = NULL; @@ -1166,17 +1165,6 @@ krb5_krcc_resolve(krb5_context context, krb5_ccache *id, const char *residual) if (ret) goto cleanup; - /* Lookup time offsets if necessary. */ - if ((context->library_options & KRB5_LIBOPT_SYNC_KDCTIME) && - !(os_ctx->os_flags & KRB5_OS_TOFFSET_VALID)) { - if (krb5_krcc_get_time_offsets(context, *id, - &os_ctx->time_offset, - &os_ctx->usec_offset) == 0) { - os_ctx->os_flags &= ~KRB5_OS_TOFFSET_TIME; - os_ctx->os_flags |= KRB5_OS_TOFFSET_VALID; - } - } - cleanup: free(anchor_name); free(collection_name); @@ -1201,6 +1189,7 @@ static krb5_error_code KRB5_CALLCONV krb5_krcc_start_seq_get(krb5_context context, krb5_ccache id, krb5_cc_cursor * cursor) { + krb5_os_context os_ctx = &context->os_context; krb5_krcc_cursor krcursor; krb5_krcc_data *d; void *keys; @@ -1238,6 +1227,18 @@ krb5_krcc_start_seq_get(krb5_context context, krb5_ccache id, k5_cc_mutex_unlock(context, &d->lock); *cursor = (krb5_cc_cursor) krcursor; + + /* Lookup time offsets if necessary. */ + if ((context->library_options & KRB5_LIBOPT_SYNC_KDCTIME) && + !(os_ctx->os_flags & KRB5_OS_TOFFSET_VALID)) { + if (krb5_krcc_get_time_offsets(context, id, + &os_ctx->time_offset, + &os_ctx->usec_offset) == 0) { + os_ctx->os_flags &= ~KRB5_OS_TOFFSET_TIME; + os_ctx->os_flags |= KRB5_OS_TOFFSET_VALID; + } + } + return KRB5_OK; } @@ -1265,6 +1266,7 @@ static krb5_error_code KRB5_CALLCONV krb5_krcc_next_cred(krb5_context context, krb5_ccache id, krb5_cc_cursor * cursor, krb5_creds * creds) { + krb5_os_context os_ctx = &context->os_context; krb5_krcc_cursor krcursor; krb5_error_code kret; int psize; @@ -1308,6 +1310,17 @@ krb5_krcc_next_cred(krb5_context context, krb5_ccache id, kret = krb5_krcc_parse_cred(context, creds, payload, psize); + /* Lookup time offsets if necessary. */ + if ((context->library_options & KRB5_LIBOPT_SYNC_KDCTIME) && + !(os_ctx->os_flags & KRB5_OS_TOFFSET_VALID)) { + if (krb5_krcc_get_time_offsets(context, id, + &os_ctx->time_offset, + &os_ctx->usec_offset) == 0) { + os_ctx->os_flags &= ~KRB5_OS_TOFFSET_TIME; + os_ctx->os_flags |= KRB5_OS_TOFFSET_VALID; + } + } + freepayload: if (payload) free(payload); return kret;