make krb5_cc_get_lifetime sane
This commit is contained in:
@@ -1127,6 +1127,7 @@ krb5_cc_cache_match (krb5_context context,
|
|||||||
krb5_cccol_cursor cursor;
|
krb5_cccol_cursor cursor;
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
krb5_ccache cache = NULL;
|
krb5_ccache cache = NULL;
|
||||||
|
krb5_ccache expired_match = NULL;
|
||||||
|
|
||||||
*id = NULL;
|
*id = NULL;
|
||||||
|
|
||||||
@@ -1134,26 +1135,46 @@ krb5_cc_cache_match (krb5_context context,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
while (krb5_cccol_cursor_next (context, cursor, &cache) == 0 && cache != NULL) {
|
while (krb5_cccol_cursor_next(context, cursor, &cache) == 0 && cache != NULL) {
|
||||||
krb5_principal principal;
|
krb5_principal principal;
|
||||||
|
krb5_boolean match;
|
||||||
|
time_t lifetime;
|
||||||
|
|
||||||
ret = krb5_cc_get_principal(context, cache, &principal);
|
ret = krb5_cc_get_principal(context, cache, &principal);
|
||||||
if (ret == 0) {
|
if (ret)
|
||||||
krb5_boolean match;
|
goto next;
|
||||||
|
|
||||||
|
if (client->name.name_string.len == 0)
|
||||||
|
match = (strcmp(client->realm, principal->realm) == 0);
|
||||||
|
else
|
||||||
match = krb5_principal_compare(context, principal, client);
|
match = krb5_principal_compare(context, principal, client);
|
||||||
krb5_free_principal(context, principal);
|
krb5_free_principal(context, principal);
|
||||||
if (match)
|
|
||||||
break;
|
if (!match)
|
||||||
}
|
goto next;
|
||||||
|
|
||||||
krb5_cc_close(context, cache);
|
if (expired_match == NULL &&
|
||||||
|
(krb5_cc_get_lifetime(context, cache, &lifetime) != 0 || lifetime == 0)) {
|
||||||
|
expired_match = cache;
|
||||||
|
cache = NULL;
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
next:
|
||||||
|
if (cache)
|
||||||
|
krb5_cc_close(context, cache);
|
||||||
cache = NULL;
|
cache = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
krb5_cccol_cursor_free(context, &cursor);
|
krb5_cccol_cursor_free(context, &cursor);
|
||||||
|
|
||||||
if (cache == NULL) {
|
if (cache == NULL && expired_match) {
|
||||||
|
cache = expired_match;
|
||||||
|
expired_match = NULL;
|
||||||
|
} else if (expired_match) {
|
||||||
|
krb5_cc_close(context, expired_match);
|
||||||
|
} else if (cache == NULL) {
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
krb5_unparse_name(context, client, &str);
|
krb5_unparse_name(context, client, &str);
|
||||||
@@ -1166,6 +1187,7 @@ krb5_cc_cache_match (krb5_context context,
|
|||||||
free(str);
|
free(str);
|
||||||
return KRB5_CC_NOTFOUND;
|
return KRB5_CC_NOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
*id = cache;
|
*id = cache;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1619,7 +1641,7 @@ krb5_cc_get_lifetime(krb5_context context, krb5_ccache id, time_t *t)
|
|||||||
krb5_cc_cursor cursor;
|
krb5_cc_cursor cursor;
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
krb5_creds cred;
|
krb5_creds cred;
|
||||||
time_t now;
|
time_t now, endtime = 0;
|
||||||
|
|
||||||
*t = 0;
|
*t = 0;
|
||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
@@ -1629,15 +1651,38 @@ krb5_cc_get_lifetime(krb5_context context, krb5_ccache id, time_t *t)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
while ((ret = krb5_cc_next_cred(context, id, &cursor, &cred)) == 0) {
|
while ((ret = krb5_cc_next_cred(context, id, &cursor, &cred)) == 0) {
|
||||||
if (cred.flags.b.initial) {
|
/**
|
||||||
|
* If we find a krbtgt in the cache, use that as the lifespan.
|
||||||
|
*/
|
||||||
|
if (krb5_principal_is_root_krbtgt(context, cred.client)) {
|
||||||
if (now < cred.times.endtime)
|
if (now < cred.times.endtime)
|
||||||
*t = cred.times.endtime - now;
|
endtime = cred.times.endtime;
|
||||||
krb5_free_cred_contents(context, &cred);
|
krb5_free_cred_contents(context, &cred);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Skip config entries
|
||||||
|
*/
|
||||||
|
if (krb5_is_config_principal(context, cred.server)) {
|
||||||
|
krb5_free_cred_contents(context, &cred);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* If there was no krbtgt, use the shortest lifetime of
|
||||||
|
* service tickets that have yet to expire. If all
|
||||||
|
* credentials are expired, krb5_cc_get_lifetime() will fail.
|
||||||
|
*/
|
||||||
|
if ((endtime == 0 || cred.times.endtime < endtime) && now < cred.times.endtime)
|
||||||
|
endtime = cred.times.endtime;
|
||||||
krb5_free_cred_contents(context, &cred);
|
krb5_free_cred_contents(context, &cred);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if we found an endtime use that */
|
||||||
|
if (endtime) {
|
||||||
|
*t = endtime - now;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
krb5_cc_end_seq_get(context, id, &cursor);
|
krb5_cc_end_seq_get(context, id, &cursor);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
Reference in New Issue
Block a user